Merge lp:~ken-vandine/content-hub/peer_details into lp:content-hub

Proposed by Ken VanDine
Status: Merged
Approved by: Bill Filler
Approved revision: 113
Merged at revision: 77
Proposed branch: lp:~ken-vandine/content-hub/peer_details
Merge into: lp:content-hub
Prerequisite: lp:~ken-vandine/content-hub/more_handlers
Diff against target: 3503 lines (+1675/-450)
59 files modified
CMakeLists.txt (+3/-0)
examples/export-qml/app-exporter.qml (+207/-0)
examples/exporter/CMakeLists.txt (+1/-1)
examples/exporter/exampleexporter.cpp (+7/-1)
examples/exporter/exampleexporter.h (+1/-1)
examples/exporter/exporter.cpp (+18/-0)
examples/importer/CMakeLists.txt (+1/-1)
examples/importer/example.cpp (+3/-4)
examples/importer/exampleimporter.cpp (+12/-5)
examples/importer/exampleimporter.h (+1/-0)
examples/importer/importer.cpp (+18/-1)
import/Ubuntu/Content/CMakeLists.txt (+15/-3)
import/Ubuntu/Content/contenthub.cpp (+175/-18)
import/Ubuntu/Content/contenthub.h (+17/-2)
import/Ubuntu/Content/contentpeer.cpp (+26/-2)
import/Ubuntu/Content/contentpeer.h (+6/-2)
import/Ubuntu/Content/contenttransfer.cpp (+36/-20)
import/Ubuntu/Content/contenttransfer.h (+4/-3)
import/Ubuntu/Content/qmlimportexporthandler.cpp (+8/-0)
import/Ubuntu/Content/qmlimportexporthandler.h (+2/-0)
include/com/ubuntu/content/hub.h (+8/-3)
include/com/ubuntu/content/import_export_handler.h (+1/-0)
include/com/ubuntu/content/peer.h (+22/-4)
include/com/ubuntu/content/transfer.h (+10/-0)
include/com/ubuntu/content/type.h (+2/-0)
libcontent-hub.pc.in (+3/-0)
src/com/ubuntu/content/CMakeLists.txt (+2/-1)
src/com/ubuntu/content/detail/app_manager.cpp (+5/-0)
src/com/ubuntu/content/detail/com.ubuntu.content.Handler.xml (+3/-0)
src/com/ubuntu/content/detail/com.ubuntu.content.Service.xml (+27/-12)
src/com/ubuntu/content/detail/com.ubuntu.content.Transfer.xml (+3/-0)
src/com/ubuntu/content/detail/handler.cpp (+18/-3)
src/com/ubuntu/content/detail/handler.h (+1/-0)
src/com/ubuntu/content/detail/peer_registry.h (+8/-5)
src/com/ubuntu/content/detail/service.cpp (+356/-138)
src/com/ubuntu/content/detail/service.h (+15/-8)
src/com/ubuntu/content/detail/transfer.cpp (+12/-2)
src/com/ubuntu/content/detail/transfer.h (+3/-1)
src/com/ubuntu/content/hub.cpp (+101/-27)
src/com/ubuntu/content/peer.cpp (+102/-7)
src/com/ubuntu/content/service/CMakeLists.txt (+2/-3)
src/com/ubuntu/content/service/com.ubuntu.content.hub.gschema.xml (+29/-1)
src/com/ubuntu/content/service/helper.cpp (+1/-1)
src/com/ubuntu/content/service/hook.cpp (+42/-30)
src/com/ubuntu/content/service/hook.h (+12/-0)
src/com/ubuntu/content/service/main.cpp (+1/-1)
src/com/ubuntu/content/service/registry.cpp (+169/-59)
src/com/ubuntu/content/service/registry.h (+12/-6)
src/com/ubuntu/content/transfer.cpp (+5/-0)
src/com/ubuntu/content/transfer_p.h (+12/-0)
src/com/ubuntu/content/utils.cpp (+13/-0)
tests/acceptance-tests/CMakeLists.txt (+14/-14)
tests/acceptance-tests/app_hub_communication_default_source.cpp (+13/-9)
tests/acceptance-tests/app_hub_communication_handler.cpp (+13/-10)
tests/acceptance-tests/app_hub_communication_known_sources.cpp (+15/-11)
tests/acceptance-tests/app_hub_communication_stores.cpp (+11/-7)
tests/acceptance-tests/app_hub_communication_transfer.cpp (+34/-12)
tests/acceptance-tests/app_manager_mock.h (+1/-1)
tests/acceptance-tests/test_hook.cpp (+13/-10)
To merge this branch: bzr merge lp:~ken-vandine/content-hub/peer_details
Reviewer Review Type Date Requested Status
Michael Sheldon (community) Approve
PS Jenkins bot continuous-integration Approve
Ubuntu Phablet Team Pending
Review via email: mp+210008@code.launchpad.net

Commit message

Marshall peer icons and name over dbus to allow display in the ContentPeerPicker with confined apps.

Description of the change

Marshall peer icons and name over dbus to allow display in the ContentPeerPicker with confined apps.

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Michael Sheldon (michael-sheldon) wrote :

ContentPeer: Is it worth keeping the iconName property given that we're unable to get the theme path and the content-hub service is populating this with image data for us (in src/com/ubuntu/content/peer.cpp)?

libcontent-hub.pc.in: ${includedir} isn't defined, also the include for QtDbus isn't necessary as this is automatically provided by the Qt5DBus requirement on the following line. However, this is already fixed in the peer_picker_ui branch, so I don't know if you just want to leave that for now?

113. By Ken VanDine

merged latest more_handlers branch

Revision history for this message
Ken VanDine (ken-vandine) wrote :

> ContentPeer: Is it worth keeping the iconName property given that we're unable
> to get the theme path and the content-hub service is populating this with
> image data for us (in src/com/ubuntu/content/peer.cpp)?

We still need the iconName in the peer for the themed icons, the service can't render them but the client can. However the client can't find the iconName based on the app, so needs the service created Peer to provide that.

>
> libcontent-hub.pc.in: ${includedir} isn't defined, also the include for QtDbus
> isn't necessary as this is automatically provided by the Qt5DBus requirement
> on the following line. However, this is already fixed in the peer_picker_ui
> branch, so I don't know if you just want to leave that for now?

I cherry picked your fix.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Michael Sheldon (michael-sheldon) wrote :

All looks good, as with the other merge request it just needs the submission template filled out.

Revision history for this message
Ken VanDine (ken-vandine) wrote :

Are there any related MPs required for this MP to build/function as expected?
 * Yes
   - https://code.launchpad.net/~ken-vandine/content-hub/more_handlers/+merge/210006
Is your branch in sync with latest trunk
 * Yes
Did you perform an exploratory manual test run of your code change and any related functionality on device or emulator?
 * Yes
Did you successfully run all tests found in your component's Test Plan (https://wiki.ubuntu.com/Process/Merges/TestPlan/content-hub) on device or emulator?
 * Yes
If you changed the UI, was the change specified/approved by design?
 * No UI changes
If you changed the packaging (debian), did you subscribe a core-dev to this MP?
 * No packaging changes

Revision history for this message
Michael Sheldon (michael-sheldon) wrote :

Did you perform an exploratory manual test run of the code change and any related functionality on device or emulator?

 * Yes, based on: https://wiki.ubuntu.com/Process/Merges/TestPlan/content-hub but using Gallery from lp:~ken-vandine/gallery-app/content_hub/ (r923) and Address Book from lp:~michael-sheldon/address-book-app/new-content-hub-api (r147) for compatibility with the content-hub API changes in this MR.

Did CI run pass? If not, please explain why.

 * Yes

Have you checked that submitter has accurately filled out the submitter checklist and has taken no shortcut?

 * Yes

review: Approve
114. By Ken VanDine

merged trunk

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'CMakeLists.txt'
2--- CMakeLists.txt 2013-12-06 12:33:14 +0000
3+++ CMakeLists.txt 2014-03-19 13:45:37 +0000
4@@ -34,6 +34,8 @@
5 set(CMAKE_INSTALL_FULL_LIBEXECDIR "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBEXECDIR}")
6 endif()
7
8+set(pkglibexecdir "${CMAKE_INSTALL_FULL_LIBEXECDIR}")
9+
10
11 #####################################################################
12 # Enable code coverage calculation with gcov/gcovr/lcov
13@@ -63,6 +65,7 @@
14 pkg_check_modules(GSETTINGS REQUIRED gsettings-qt)
15 pkg_check_modules(NIH REQUIRED libnih)
16 pkg_check_modules(NIH_DBUS REQUIRED libnih-dbus)
17+pkg_check_modules(DBUS REQUIRED dbus-1)
18
19 set(CONTENT_HUB_VERSION_MAJOR 0)
20 set(CONTENT_HUB_VERSION_MINOR 0)
21
22=== added file 'examples/export-qml/app-exporter.qml'
23--- examples/export-qml/app-exporter.qml 1970-01-01 00:00:00 +0000
24+++ examples/export-qml/app-exporter.qml 2014-03-19 13:45:37 +0000
25@@ -0,0 +1,207 @@
26+import QtQuick 2.0
27+import Ubuntu.Components 0.1
28+import Ubuntu.Components.Popups 0.1
29+import Ubuntu.Components.ListItems 0.1 as ListItem
30+import Ubuntu.Content 0.1
31+
32+MainView {
33+ id: root
34+ applicationName: "com.ubuntu.developer.ken-vandine.hub-exporter"
35+ width: units.gu(50)
36+ height: units.gu(60)
37+
38+ property bool pickMode: activeTransfer.state === ContentTransfer.InProgress
39+ property var selectedItems: []
40+ property var activeTransfer
41+
42+ function __returnResult() {
43+ activeTransfer.items = selectedItems;
44+ activeTransfer.state = ContentTransfer.Charged;
45+ }
46+
47+ ListModel {
48+ id: images
49+
50+ ListElement {
51+ src: "file:///usr/share/icons/hicolor/128x128/apps/ubuntuone-music.png"
52+ }
53+
54+ ListElement {
55+ src: "file:///usr/share/icons/hicolor/128x128/apps/ubuntuone-music.png"
56+ }
57+
58+ ListElement {
59+ src: "file:///usr/share/icons/hicolor/128x128/apps/ubuntuone-music.png"
60+ }
61+
62+ ListElement {
63+ src: "file:///usr/share/icons/hicolor/128x128/apps/ubuntuone-music.png"
64+ }
65+ }
66+
67+ GridView {
68+ anchors.fill: parent
69+ model: images
70+ cellWidth: 128
71+ cellHeight: 128
72+ delegate: itemDelegate
73+ }
74+
75+ Component {
76+ id: resultComponent
77+ ContentItem {}
78+ }
79+
80+ Component {
81+ id: itemDelegate
82+ Item {
83+ width: 128
84+ height: 128
85+
86+ property bool isSelected: false
87+
88+ UbuntuShape {
89+ width: parent.width
90+ height: width
91+ image: Image {
92+ id: image
93+ source: src
94+ height: parent.width
95+ width: height
96+ fillMode: Image.PreserveAspectFit
97+ smooth: true
98+ }
99+
100+ MouseArea {
101+ anchors.fill: parent
102+ enabled: pickMode
103+ onClicked: {
104+ var shouldAdd = true;
105+ for (var i = 0; i < selectedItems.length; i++)
106+ {
107+ console.log("item: ", selectedItems[i]);
108+ if (selectedItems[i] === src)
109+ {
110+ selectedItems.pop(i);
111+ shouldAdd = false;
112+ isSelected = false;
113+ }
114+ }
115+ if (shouldAdd)
116+ {
117+ selectedItems.push(src);
118+ isSelected = true;
119+ }
120+ }
121+ }
122+
123+ Image {
124+ id: selectionTick
125+ anchors.right: parent.right
126+ anchors.top: parent.top
127+ width: units.gu(5)
128+ height: units.gu(5)
129+ visible: isSelected
130+ source: "photo-preview-selected-overlay.png"
131+ }
132+
133+ MouseArea {
134+ anchors.fill: parent
135+ enabled: !pickMode
136+ onClicked: {
137+ actPop.show();
138+ }
139+ }
140+
141+ ActionSelectionPopover {
142+ id: actPop
143+ delegate: ListItem.Standard {
144+ text: action.text
145+ }
146+
147+ contentWidth: childrenRect.width
148+
149+ actions: ActionList {
150+ Action {
151+ text: "Open with..."
152+ onTriggered: {
153+ print(text + ": " + src);
154+ activeTransfer = ContentHub.exportContent(ContentType.Pictures, picDest);
155+ activeTransfer.items = [ resultComponent.createObject(root, {"url": src}) ];
156+ actPop.hide();
157+ }
158+ }
159+ Action {
160+ text: "Share"
161+ onTriggered: {
162+ print(text + ": " + src);
163+ activeTransfer = ContentHub.shareContent(ContentType.Pictures, picShare);
164+ activeTransfer.items = [ resultComponent.createObject(root, {"url": src}) ];
165+ actPop.hide();
166+ }
167+ }
168+ }
169+ }
170+ }
171+ }
172+ }
173+
174+ ContentPeer {
175+ id: picDest
176+ appId: "com.ubuntu.developer.ken-vandine.hub-importer_hub-importer_0.2"
177+ }
178+
179+ ContentPeer {
180+ id: picShare
181+ appId: "com.ubuntu.developer.ken-vandine.hub-share_hub-share_0.2"
182+ }
183+
184+ ContentImportHint {
185+ anchors.fill: parent
186+ activeTransfer: activeTransfer
187+ }
188+
189+ Connections {
190+ target: ContentHub
191+ onExportRequested: {
192+ activeTransfer = transfer
193+ }
194+ }
195+
196+ ListItem.Empty {
197+ id: pickerButtons
198+ anchors {
199+ left: parent.left
200+ right: parent.right
201+ bottom: parent.bottom
202+ margins: units.gu(2)
203+ }
204+ visible: pickMode
205+ Button {
206+ anchors {
207+ left: parent.left
208+ bottom: parent.bottom
209+ margins: units.gu(2)
210+ }
211+ text: "Cancel"
212+ onClicked: activeTransfer.state = ContentTransfer.Aborted;
213+ }
214+
215+ Button {
216+ anchors {
217+ right: parent.right
218+ bottom: parent.bottom
219+ margins: units.gu(2)
220+ }
221+ text: "Select"
222+ onClicked: {
223+ var results = [];
224+ for (var i = 0; i < selectedItems.length; i++)
225+ results.push(resultComponent.createObject(root, {"url": selectedItems[i]}));
226+
227+ if (results.length > 0)
228+ activeTransfer.items = results;
229+ }
230+ }
231+ }
232+}
233
234=== modified file 'examples/exporter/CMakeLists.txt'
235--- examples/exporter/CMakeLists.txt 2013-08-28 18:22:37 +0000
236+++ examples/exporter/CMakeLists.txt 2014-03-19 13:45:37 +0000
237@@ -23,7 +23,7 @@
238 exampleexporter.cpp
239 )
240
241-qt5_use_modules(exporter Core)
242+qt5_use_modules(exporter Core Gui DBus)
243
244 set_target_properties(
245 exporter
246
247=== modified file 'examples/exporter/exampleexporter.cpp'
248--- examples/exporter/exampleexporter.cpp 2013-09-05 18:49:34 +0000
249+++ examples/exporter/exampleexporter.cpp 2014-03-19 13:45:37 +0000
250@@ -24,6 +24,12 @@
251 hub->register_import_export_handler(this);
252 }
253
254+void ExampleExporter::handle_import(cuc::Transfer *transfer)
255+{
256+ qDebug() << Q_FUNC_INFO << "not implemented";
257+ Q_UNUSED(transfer);
258+}
259+
260 void ExampleExporter::handle_export(cuc::Transfer *transfer)
261 {
262 qDebug() << Q_FUNC_INFO;
263@@ -45,7 +51,7 @@
264 qDebug() << Q_FUNC_INFO << "Items:" << items.count();
265 }
266
267-void ExampleExporter::handle_import(cuc::Transfer *transfer)
268+void ExampleExporter::handle_share(cuc::Transfer *transfer)
269 {
270 qDebug() << Q_FUNC_INFO << "not implemented";
271 Q_UNUSED(transfer);
272
273=== modified file 'examples/exporter/exampleexporter.h'
274--- examples/exporter/exampleexporter.h 2013-08-29 15:51:28 +0000
275+++ examples/exporter/exampleexporter.h 2014-03-19 13:45:37 +0000
276@@ -37,7 +37,7 @@
277 public slots:
278 Q_INVOKABLE void handle_import(cuc::Transfer*);
279 Q_INVOKABLE void handle_export(cuc::Transfer*);
280-
281+ Q_INVOKABLE void handle_share(cuc::Transfer*);
282 };
283
284 #endif // EXAMPLEEXPORTER_H
285
286=== modified file 'examples/exporter/exporter.cpp'
287--- examples/exporter/exporter.cpp 2013-08-29 15:51:28 +0000
288+++ examples/exporter/exporter.cpp 2014-03-19 13:45:37 +0000
289@@ -17,6 +17,8 @@
290 */
291
292 #include <QCoreApplication>
293+#include <QStringList>
294+
295
296 #include "exampleexporter.h"
297
298@@ -31,5 +33,21 @@
299
300 ExampleExporter exporter;
301
302+ QString peerName;
303+
304+ if (a.arguments().size() > 1)
305+ peerName = a.arguments().at(1);
306+
307+ if (!peerName.isEmpty())
308+ {
309+ qDebug() << peerName;
310+ auto hub = cuc::Hub::Client::instance();
311+
312+ auto peer = cuc::Peer{peerName};
313+ qDebug() << Q_FUNC_INFO << "PEER: " << peer.id();
314+ auto transfer = hub->create_export_to_peer(peer);
315+ exporter.handle_export(transfer);
316+ }
317+
318 return a.exec();
319 }
320
321=== modified file 'examples/importer/CMakeLists.txt'
322--- examples/importer/CMakeLists.txt 2013-08-28 18:22:37 +0000
323+++ examples/importer/CMakeLists.txt 2014-03-19 13:45:37 +0000
324@@ -24,7 +24,7 @@
325 example.cpp
326 )
327
328-qt5_use_modules(importer Core)
329+qt5_use_modules(importer Core Gui DBus)
330
331 set_target_properties(
332 importer
333
334=== modified file 'examples/importer/example.cpp'
335--- examples/importer/example.cpp 2013-10-01 16:55:39 +0000
336+++ examples/importer/example.cpp 2014-03-19 13:45:37 +0000
337@@ -30,12 +30,11 @@
338 {
339 auto hub = cuc::Hub::Client::instance();
340
341- auto peer = hub->default_peer_for_type(cuc::Type::Known::pictures());
342+ auto peer = hub->default_source_for_type(cuc::Type::Known::pictures());
343+
344 qDebug() << Q_FUNC_INFO << "PEER: " << peer.name();
345
346- m_transfer = hub->create_import_for_type_from_peer(
347- cuc::Type::Known::pictures(),
348- peer);
349+ m_transfer = hub->create_import_from_peer(peer);
350
351 /* Uncommit this for persistent storage
352 auto store = hub->store_for_scope_and_type(cuc::Scope::app, cuc::Type::Known::pictures());
353
354=== modified file 'examples/importer/exampleimporter.cpp'
355--- examples/importer/exampleimporter.cpp 2013-10-01 16:55:39 +0000
356+++ examples/importer/exampleimporter.cpp 2014-03-19 13:45:37 +0000
357@@ -25,11 +25,6 @@
358 hub->register_import_export_handler(this);
359 }
360
361-void ExampleImporter::handle_export(cuc::Transfer *transfer)
362-{
363- qDebug() << Q_FUNC_INFO << "not implemented";
364- Q_UNUSED(transfer);
365-}
366
367 void ExampleImporter::handle_import(cuc::Transfer *transfer)
368 {
369@@ -40,3 +35,15 @@
370 qDebug() << Q_FUNC_INFO << "Item:" << item.url();
371 transfer->finalize();
372 }
373+
374+void ExampleImporter::handle_export(cuc::Transfer *transfer)
375+{
376+ qDebug() << Q_FUNC_INFO << "not implemented";
377+ Q_UNUSED(transfer);
378+}
379+
380+void ExampleImporter::handle_share(cuc::Transfer *transfer)
381+{
382+ qDebug() << Q_FUNC_INFO << "not implemented";
383+ Q_UNUSED(transfer);
384+}
385
386=== modified file 'examples/importer/exampleimporter.h'
387--- examples/importer/exampleimporter.h 2013-08-28 18:22:37 +0000
388+++ examples/importer/exampleimporter.h 2014-03-19 13:45:37 +0000
389@@ -34,6 +34,7 @@
390 ExampleImporter();
391 Q_INVOKABLE void handle_import(cuc::Transfer*);
392 Q_INVOKABLE void handle_export(cuc::Transfer*);
393+ Q_INVOKABLE void handle_share(cuc::Transfer*);
394 };
395
396 #endif // EXAMPLEIMPORTER_H
397
398=== modified file 'examples/importer/importer.cpp'
399--- examples/importer/importer.cpp 2013-08-20 16:21:15 +0000
400+++ examples/importer/importer.cpp 2014-03-19 13:45:37 +0000
401@@ -17,6 +17,7 @@
402 */
403
404 #include <QCoreApplication>
405+#include <QStringList>
406 #include "example.h"
407
408 namespace cuc = com::ubuntu::content;
409@@ -27,7 +28,23 @@
410
411 Example *e = new Example();
412
413- e->create_import();
414+ QString peerName;
415+
416+ if (a.arguments().size() > 1)
417+ peerName = a.arguments().at(1);
418+
419+ if (!peerName.isEmpty())
420+ {
421+ qDebug() << peerName;
422+ auto hub = cuc::Hub::Client::instance();
423+
424+ auto peer = cuc::Peer{peerName};
425+ qDebug() << Q_FUNC_INFO << "PEER: " << peer.id();
426+ auto transfer = hub->create_import_from_peer(peer);
427+ transfer->start();
428+ }
429+
430+ Q_UNUSED(e);
431
432 return a.exec();
433 }
434
435=== modified file 'import/Ubuntu/Content/CMakeLists.txt'
436--- import/Ubuntu/Content/CMakeLists.txt 2013-10-01 16:55:39 +0000
437+++ import/Ubuntu/Content/CMakeLists.txt 2014-03-19 13:45:37 +0000
438@@ -26,7 +26,14 @@
439
440 set(PLUGIN ubuntu-content-hub-plugin)
441
442-include_directories(${CMAKE_SOURCE_DIR})
443+add_definitions(-DQT_NO_KEYWORDS)
444+
445+include_directories(
446+ ${CMAKE_SOURCE_DIR}
447+ ${NIH_INCLUDE_DIRS}
448+ ${NIH_DBUS_INCLUDE_DIRS}
449+ ${DBUS_INCLUDE_DIRS}
450+)
451
452 set(PLUGIN_HDRS
453 contenthub.h
454@@ -52,8 +59,13 @@
455
456 add_library(${PLUGIN} MODULE ${PLUGIN_SRC} ${PLUGIN_HDRS})
457
458-qt5_use_modules(${PLUGIN} Core Qml Quick)
459-target_link_libraries(${PLUGIN} content-hub)
460+qt5_use_modules(${PLUGIN} Core Qml Quick DBus)
461+target_link_libraries(
462+ ${PLUGIN}
463+ content-hub
464+ ${NIH_LIBRARIES}
465+ ${NIH_DBUS_LIBRARIES}
466+)
467
468 install(TARGETS ${PLUGIN} DESTINATION ${CONTENT_HUB_IMPORTS_DIR})
469 install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/qmldir DESTINATION ${CONTENT_HUB_IMPORTS_DIR})
470
471=== modified file 'import/Ubuntu/Content/contenthub.cpp'
472--- import/Ubuntu/Content/contenthub.cpp 2013-11-18 22:16:50 +0000
473+++ import/Ubuntu/Content/contenthub.cpp 2014-03-19 13:45:37 +0000
474@@ -25,6 +25,7 @@
475 #include <com/ubuntu/content/peer.h>
476 #include <com/ubuntu/content/type.h>
477
478+#include <QStringList>
479 #include <QDebug>
480
481 /*!
482@@ -115,6 +116,8 @@
483 this, SLOT(handleImport(com::ubuntu::content::Transfer*)));
484 connect(m_handler, SIGNAL(exportRequested(com::ubuntu::content::Transfer*)),
485 this, SLOT(handleExport(com::ubuntu::content::Transfer*)));
486+ connect(m_handler, SIGNAL(shareRequested(com::ubuntu::content::Transfer*)),
487+ this, SLOT(handleShare(com::ubuntu::content::Transfer*)));
488 }
489
490 /*!
491@@ -127,7 +130,7 @@
492 qDebug() << Q_FUNC_INFO;
493
494 const cuc::Type &hubType = ContentType::contentType2HubType(type);
495- cuc::Peer hubPeer = m_hub->default_peer_for_type(hubType);
496+ cuc::Peer hubPeer = m_hub->default_source_for_type(hubType);
497
498 ContentPeer *qmlPeer = new ContentPeer(this);
499 qmlPeer->setPeer(hubPeer);
500@@ -188,10 +191,10 @@
501 qDebug() << Q_FUNC_INFO;
502
503 const cuc::Type &hubType = ContentType::contentType2HubType(type);
504- QVector<cuc::Peer> hubPeers = m_hub->known_peers_for_type(hubType);
505+ QVector<cuc::Peer> hubPeers = m_hub->known_sources_for_type(hubType);
506
507 QVariantList qmlPeers;
508- foreach (const cuc::Peer &hubPeer, hubPeers) {
509+ Q_FOREACH (const cuc::Peer &hubPeer, hubPeers) {
510 ContentPeer *qmlPeer = new ContentPeer(this);
511 qmlPeer->setPeer(hubPeer);
512 qmlPeers.append(QVariant::fromValue(qmlPeer));
513@@ -211,8 +214,7 @@
514 qDebug() << Q_FUNC_INFO << static_cast<ContentType::Type>(type);
515
516 const cuc::Type &hubType = ContentType::contentType2HubType(type);
517-// FIXME show user a selection of possible peers instead
518- cuc::Peer hubPeer = m_hub->default_peer_for_type(hubType);
519+ cuc::Peer hubPeer = m_hub->default_source_for_type(hubType);
520
521 return importContent(hubType, hubPeer);
522 }
523@@ -238,16 +240,12 @@
524 * \a peer
525 * \internal
526 */
527-ContentTransfer* ContentHub::importContent(const com::ubuntu::content::Type &hubType,
528+ContentTransfer* ContentHub::importContent(const com::ubuntu::content::Type& /*hubType*/,
529 const com::ubuntu::content::Peer &hubPeer)
530 {
531- cuc::Transfer *hubTransfer = m_hub->create_import_for_type_from_peer(hubType, hubPeer);
532-// FIXME update tests so this can be enabled
533-// if (!hubTransfer)
534-// return nullptr;
535-
536+ cuc::Transfer *hubTransfer = m_hub->create_import_from_peer(hubPeer);
537 ContentTransfer *qmlTransfer = new ContentTransfer(this);
538- qmlTransfer->setTransfer(hubTransfer, ContentTransfer::Import);
539+ qmlTransfer->setTransfer(hubTransfer);
540 m_activeImports.insert(hubTransfer, qmlTransfer);
541 return qmlTransfer;
542 }
543@@ -271,6 +269,103 @@
544 return QQmlListProperty<ContentTransfer>(this, m_finishedImports);
545 }
546
547+/* EXPORTS */
548+/*!
549+ * \qmlmethod ContentHub::exportContent(ContentType)
550+ * \overload ContentHub::exportContent(ContentType, ContentPeer)
551+ *
552+ * \brief Request to export data of \a ContentType to the default
553+ * ContentPeer
554+ */
555+ContentTransfer *ContentHub::exportContent(int type)
556+{
557+ qDebug() << Q_FUNC_INFO << static_cast<ContentType::Type>(type);
558+
559+ const cuc::Type &hubType = ContentType::contentType2HubType(type);
560+ cuc::Peer hubPeer = m_hub->default_source_for_type(hubType);
561+ return exportContent(hubType, hubPeer);
562+}
563+
564+/*!
565+ * \qmlmethod ContentHub::exportContent(ContentType, ContentPeer)
566+ * \overload ContentHub::exportContent(ContentType)
567+ *
568+ * \brief Request to export data of \a ContentType to the
569+ * specified \a ContentPeer
570+ */
571+ContentTransfer *ContentHub::exportContent(int type, ContentPeer *peer)
572+{
573+ qDebug() << Q_FUNC_INFO << static_cast<ContentType::Type>(type) << peer;
574+
575+ const cuc::Type &hubType = ContentType::contentType2HubType(type);
576+ return exportContent(hubType, peer->peer());
577+}
578+
579+/*!
580+ * \brief ContentHub::exportContent creates a ContentTransfer object
581+ * \a type
582+ * \a peer
583+ * \internal
584+ */
585+ContentTransfer* ContentHub::exportContent(const com::ubuntu::content::Type& /*hubType*/,
586+ const com::ubuntu::content::Peer &hubPeer)
587+{
588+ cuc::Transfer *hubTransfer = m_hub->create_export_to_peer(hubPeer);
589+ ContentTransfer *qmlTransfer = new ContentTransfer(this);
590+ qmlTransfer->setTransfer(hubTransfer);
591+ m_activeImports.insert(hubTransfer, qmlTransfer);
592+ return qmlTransfer;
593+}
594+
595+/* SHARE */
596+/*!
597+ * \qmlmethod ContentHub::shareContent(ContentType)
598+ * \overload ContentHub::shareContent(ContentType, ContentPeer)
599+ *
600+ * \brief Request to share data of \a ContentType to the default
601+ * ContentPeer
602+ */
603+ContentTransfer *ContentHub::shareContent(int type)
604+{
605+ qDebug() << Q_FUNC_INFO << static_cast<ContentType::Type>(type);
606+
607+ const cuc::Type &hubType = ContentType::contentType2HubType(type);
608+ // FIXME: This is the wrong way to get the default peer for shares
609+ cuc::Peer hubPeer = m_hub->default_source_for_type(hubType);
610+ return shareContent(hubType, hubPeer);
611+}
612+
613+/*!
614+ * \qmlmethod ContentHub::shareContent(ContentType, ContentPeer)
615+ * \overload ContentHub::shareContent(ContentType)
616+ *
617+ * \brief Request to share data of \a ContentType to the
618+ * specified \a ContentPeer
619+ */
620+ContentTransfer *ContentHub::shareContent(int type, ContentPeer *peer)
621+{
622+ qDebug() << Q_FUNC_INFO << static_cast<ContentType::Type>(type) << peer;
623+
624+ const cuc::Type &hubType = ContentType::contentType2HubType(type);
625+ return shareContent(hubType, peer->peer());
626+}
627+
628+/*!
629+ * \brief ContentHub::shareContent creates a ContentTransfer object
630+ * \a type
631+ * \a peer
632+ * \internal
633+ */
634+ContentTransfer* ContentHub::shareContent(const com::ubuntu::content::Type& /*hubType*/,
635+ const com::ubuntu::content::Peer &hubPeer)
636+{
637+ cuc::Transfer *hubTransfer = m_hub->create_share_to_peer(hubPeer);
638+ ContentTransfer *qmlTransfer = new ContentTransfer(this);
639+ qmlTransfer->setTransfer(hubTransfer);
640+ m_activeImports.insert(hubTransfer, qmlTransfer);
641+ return qmlTransfer;
642+}
643+
644 /*!
645 * \brief ContentHub::handleImport handles an incoming request for importing content
646 * \internal
647@@ -283,8 +378,14 @@
648 qmlTransfer = m_activeImports.take(transfer);
649 qmlTransfer->collectItems();
650 } else {
651+ // If we don't have a reference to the transfer, it was created
652+ // by another handler so this would be an Import
653 qmlTransfer = new ContentTransfer(this);
654- qmlTransfer->setTransfer(transfer, ContentTransfer::Import);
655+ qmlTransfer->setTransfer(transfer);
656+ connect(qmlTransfer, SIGNAL(stateChanged()),
657+ this, SLOT(updateState()));
658+ qmlTransfer->collectItems();
659+ Q_EMIT importRequested(qmlTransfer);
660 }
661
662 m_finishedImports.append(qmlTransfer);
663@@ -298,11 +399,61 @@
664 void ContentHub::handleExport(com::ubuntu::content::Transfer *transfer)
665 {
666 qDebug() << Q_FUNC_INFO;
667- ContentTransfer *qmlTransfer = new ContentTransfer(this);
668- qmlTransfer->setTransfer(transfer, ContentTransfer::Export);
669-
670- Q_EMIT exportRequested(qmlTransfer);
671-}
672+ ContentTransfer *qmlTransfer = nullptr;
673+ if (m_activeImports.contains(transfer))
674+ qmlTransfer = m_activeImports.take(transfer);
675+ else {
676+ // If we don't have a reference to the transfer, it was created
677+ // by another handler so this would be an Import
678+ qmlTransfer = new ContentTransfer(this);
679+ qmlTransfer->setTransfer(transfer);
680+ m_activeImports.insert(transfer, qmlTransfer);
681+ connect(qmlTransfer, SIGNAL(stateChanged()),
682+ this, SLOT(updateState()));
683+ Q_EMIT exportRequested(qmlTransfer);
684+ }
685+
686+ m_finishedImports.append(qmlTransfer);
687+ Q_EMIT finishedImportsChanged();
688+}
689+
690+/*!
691+ * \brief ContentHub::handleExport handles an incoming request for sharing content
692+ * \internal
693+ */
694+void ContentHub::handleShare(com::ubuntu::content::Transfer *transfer)
695+{
696+ qDebug() << Q_FUNC_INFO;
697+ ContentTransfer *qmlTransfer = nullptr;
698+ if (m_activeImports.contains(transfer))
699+ {
700+ qmlTransfer = m_activeImports.take(transfer);
701+ qmlTransfer->collectItems();
702+ } else {
703+ // If we don't have a reference to the transfer, it was created
704+ // by another handler so this would be an Import
705+ qmlTransfer = new ContentTransfer(this);
706+ qmlTransfer->setTransfer(transfer);
707+ connect(qmlTransfer, SIGNAL(stateChanged()),
708+ this, SLOT(updateState()));
709+ qmlTransfer->collectItems();
710+ Q_EMIT shareRequested(qmlTransfer);
711+ }
712+
713+ m_finishedImports.append(qmlTransfer);
714+ Q_EMIT finishedImportsChanged();
715+}
716+
717+void ContentHub::updateState()
718+{
719+ qDebug() << Q_FUNC_INFO;
720+}
721+
722+/*!
723+ * \qmlsignal ContentHub::importRequested(ContentTransfer transfer)
724+ *
725+ * The signal is triggered when an import is requested.
726+ */
727
728 /*!
729 * \qmlsignal ContentHub::exportRequested(ContentTransfer transfer)
730@@ -310,3 +461,9 @@
731 * The signal is triggered when an export is requested.
732 */
733
734+/*!
735+ * \qmlsignal ContentHub::shareRequested(ContentTransfer transfer)
736+ *
737+ * The signal is triggered when a share is requested.
738+ */
739+
740
741=== modified file 'import/Ubuntu/Content/contenthub.h'
742--- import/Ubuntu/Content/contenthub.h 2013-11-07 20:12:56 +0000
743+++ import/Ubuntu/Content/contenthub.h 2014-03-19 13:45:37 +0000
744@@ -55,25 +55,40 @@
745 Q_INVOKABLE ContentTransfer* importContent(int type);
746 Q_INVOKABLE ContentTransfer* importContent(int type, ContentPeer *peer);
747
748+ Q_INVOKABLE ContentTransfer* exportContent(int type);
749+ Q_INVOKABLE ContentTransfer* exportContent(int type, ContentPeer *peer);
750+
751+ Q_INVOKABLE ContentTransfer* shareContent(int type);
752+ Q_INVOKABLE ContentTransfer* shareContent(int type, ContentPeer *peer);
753+
754 Q_INVOKABLE void restoreImports();
755
756 QQmlListProperty<ContentTransfer> finishedImports();
757
758 Q_SIGNALS:
759+ void importRequested(ContentTransfer *transfer);
760 void exportRequested(ContentTransfer *transfer);
761+ void shareRequested(ContentTransfer *transfer);
762+
763 void finishedImportsChanged();
764
765 private Q_SLOTS:
766 void handleImport(com::ubuntu::content::Transfer * transfer);
767 void handleExport(com::ubuntu::content::Transfer * transfer);
768+ void handleShare(com::ubuntu::content::Transfer * transfer);
769+ void updateState();
770
771 private:
772- ContentTransfer* importContent(const com::ubuntu::content::Type &hubType,
773+ ContentTransfer* importContent(const com::ubuntu::content::Type&,
774+ const com::ubuntu::content::Peer &hubPeer);
775+
776+ ContentTransfer* exportContent(const com::ubuntu::content::Type&,
777+ const com::ubuntu::content::Peer &hubPeer);
778+ ContentTransfer* shareContent(const com::ubuntu::content::Type&,
779 const com::ubuntu::content::Peer &hubPeer);
780
781 QList<ContentTransfer *> m_finishedImports;
782 QHash<com::ubuntu::content::Transfer *, ContentTransfer *> m_activeImports;
783-
784 com::ubuntu::content::Hub *m_hub;
785 QmlImportExportHandler *m_handler;
786 };
787
788=== modified file 'import/Ubuntu/Content/contentpeer.cpp'
789--- import/Ubuntu/Content/contentpeer.cpp 2013-11-07 20:12:56 +0000
790+++ import/Ubuntu/Content/contentpeer.cpp 2014-03-19 13:45:37 +0000
791@@ -15,10 +15,9 @@
792 */
793
794 #include "contentpeer.h"
795-
796 #include <com/ubuntu/content/peer.h>
797-
798 #include <QDebug>
799+#include <QIcon>
800
801 /*!
802 * \qmltype ContentPeer
803@@ -64,6 +63,23 @@
804 }
805
806 /*!
807+ * \brief ContentPeer::setAppId
808+ *
809+ * Sets the Application id
810+ */
811+void ContentPeer::setAppId(const QString& appId)
812+{
813+ qDebug() << Q_FUNC_INFO << appId;
814+ this->setPeer(cuc::Peer{appId});
815+}
816+
817+QImage &ContentPeer::icon()
818+{
819+ qDebug() << Q_FUNC_INFO;
820+ return m_icon;
821+}
822+
823+/*!
824 * \brief ContentPeer::peer
825 * \internal
826 */
827@@ -78,7 +94,15 @@
828 */
829 void ContentPeer::setPeer(const cuc::Peer &peer)
830 {
831+ qDebug() << Q_FUNC_INFO;
832 m_peer = peer;
833+ if (peer.icon().isNull())
834+ {
835+ if (QIcon::hasThemeIcon(peer.iconName().toUtf8()))
836+ m_icon = QIcon::fromTheme(peer.iconName().toUtf8()).pixmap(256).toImage();
837+ } else
838+ m_icon = peer.icon();
839+
840 Q_EMIT nameChanged();
841 Q_EMIT appIdChanged();
842 }
843
844=== modified file 'import/Ubuntu/Content/contentpeer.h'
845--- import/Ubuntu/Content/contentpeer.h 2013-10-23 12:06:13 +0000
846+++ import/Ubuntu/Content/contentpeer.h 2014-03-19 13:45:37 +0000
847@@ -21,18 +21,21 @@
848
849 #include <QObject>
850 #include <QString>
851-
852+#include <QImage>
853 class ContentPeer : public QObject
854 {
855 Q_OBJECT
856 Q_PROPERTY(QString name READ name NOTIFY nameChanged)
857- Q_PROPERTY(QString appId READ appId NOTIFY appIdChanged)
858+ Q_PROPERTY(QString appId READ appId WRITE setAppId NOTIFY appIdChanged)
859+ Q_PROPERTY(QImage icon READ icon)
860
861 public:
862 ContentPeer(QObject *parent = nullptr);
863
864 QString name();
865 const QString &appId() const;
866+ void setAppId(const QString&);
867+ QImage &icon();
868
869 const com::ubuntu::content::Peer &peer() const;
870 void setPeer(const com::ubuntu::content::Peer &peer);
871@@ -43,6 +46,7 @@
872
873 private:
874 com::ubuntu::content::Peer m_peer;
875+ QImage m_icon;
876 };
877
878 #endif // COM_UBUNTU_CONTENTPEER_H_
879
880=== modified file 'import/Ubuntu/Content/contenttransfer.cpp'
881--- import/Ubuntu/Content/contenttransfer.cpp 2013-10-22 20:44:52 +0000
882+++ import/Ubuntu/Content/contenttransfer.cpp 2014-03-19 13:45:37 +0000
883@@ -82,18 +82,24 @@
884
885 void ContentTransfer::setState(ContentTransfer::State state)
886 {
887- qDebug() << Q_FUNC_INFO;
888+ qDebug() << Q_FUNC_INFO << state;
889 if (!m_transfer)
890 return;
891
892- if (state == Charged && m_state == InProgress && m_direction == Export) {
893+ if (state == Charged && m_state == InProgress) {
894+ qDebug() << Q_FUNC_INFO << "Charged";
895 QVector<cuc::Item> hubItems;
896 hubItems.reserve(m_items.size());
897- foreach (const ContentItem *citem, m_items) {
898+ Q_FOREACH (const ContentItem *citem, m_items) {
899 hubItems.append(citem->item());
900 }
901 m_transfer->charge(hubItems);
902- }
903+ return;
904+ } else if (state == Aborted) {
905+ qDebug() << Q_FUNC_INFO << "Aborted";
906+ m_transfer->abort();
907+ } else
908+ updateState();
909 }
910
911 /*!
912@@ -112,6 +118,9 @@
913 \row
914 \li ContentTransfer.Export
915 \li Transfer is a request to export content.
916+ \row
917+ \li ContentTransfer.Share
918+ \li Transfer is a request to share content.
919 \endtable
920 */
921 ContentTransfer::Direction ContentTransfer::direction() const
922@@ -161,7 +170,7 @@
923 QQmlListProperty<ContentItem> ContentTransfer::items()
924 {
925 qDebug() << Q_FUNC_INFO;
926- if (m_state == Charged && m_direction == Import) {
927+ if (m_state == Charged) {
928 collectItems();
929 }
930 return QQmlListProperty<ContentItem>(this, m_items);
931@@ -174,7 +183,7 @@
932 */
933 bool ContentTransfer::start()
934 {
935- qDebug() << Q_FUNC_INFO;
936+ qDebug() << Q_FUNC_INFO << m_transfer->id() << ":" << m_state;
937 if (m_state == Created) {
938 return m_transfer->start();
939 } else {
940@@ -230,7 +239,7 @@
941 * \brief ContentTransfer::setTransfer
942 * \internal
943 */
944-void ContentTransfer::setTransfer(com::ubuntu::content::Transfer *transfer, Direction direction)
945+void ContentTransfer::setTransfer(com::ubuntu::content::Transfer *transfer)
946 {
947 if (m_transfer) {
948 qWarning() << Q_FUNC_INFO << "the transfer object was already set";
949@@ -242,21 +251,17 @@
950 return;
951 }
952
953- qDebug() << Q_FUNC_INFO;
954-
955- m_direction = direction;
956 m_transfer = transfer;
957+ m_direction = static_cast<ContentTransfer::Direction>(transfer->direction());
958+ qDebug() << Q_FUNC_INFO << "Direction:" << m_direction;
959+
960+ connect(m_transfer, SIGNAL(selectionTypeChanged()), this, SLOT(updateSelectionType()));
961+ connect(m_transfer, SIGNAL(storeChanged()), this, SLOT(updateStore()));
962+ connect(m_transfer, SIGNAL(stateChanged()), this, SLOT(updateState()));
963
964 updateSelectionType();
965 updateStore();
966 updateState();
967-
968- if (m_state == Charged && m_direction == Import)
969- collectItems();
970-
971- connect(m_transfer, SIGNAL(selectionTypeChanged()), this, SLOT(updateSelectionType()));
972- connect(m_transfer, SIGNAL(storeChanged()), this, SLOT(updateStore()));
973- connect(m_transfer, SIGNAL(stateChanged()), this, SLOT(updateState()));
974 }
975
976 /*!
977@@ -266,14 +271,14 @@
978 void ContentTransfer::collectItems()
979 {
980 qDebug() << Q_FUNC_INFO;
981- if (m_state != Charged || m_direction != Import)
982+ if (m_state != Charged)
983 return;
984
985 qDeleteAll(m_items);
986 m_items.clear();
987
988 QVector<cuc::Item> transfereditems = m_transfer->collect();
989- foreach (const cuc::Item &hubItem, transfereditems) {
990+ Q_FOREACH (const cuc::Item &hubItem, transfereditems) {
991 ContentItem *qmlItem = new ContentItem(this);
992 qmlItem->setItem(hubItem);
993 m_items.append(qmlItem);
994@@ -287,11 +292,16 @@
995 */
996 void ContentTransfer::updateState()
997 {
998- qDebug() << Q_FUNC_INFO;
999+ qDebug() << Q_FUNC_INFO << m_transfer->state();
1000+
1001 if (!m_transfer)
1002+ {
1003+ qWarning() << Q_FUNC_INFO << "Invalid transfer";
1004 return;
1005+ }
1006
1007 m_state = static_cast<ContentTransfer::State>(m_transfer->state());
1008+ qDebug() << Q_FUNC_INFO << "m_state";
1009 Q_EMIT stateChanged();
1010 }
1011
1012@@ -303,7 +313,10 @@
1013 {
1014 qDebug() << Q_FUNC_INFO;
1015 if (!m_transfer)
1016+ {
1017+ qWarning() << Q_FUNC_INFO << "Invalid transfer";
1018 return;
1019+ }
1020
1021 m_selectionType = static_cast<ContentTransfer::SelectionType>(m_transfer->selectionType());
1022 Q_EMIT selectionTypeChanged();
1023@@ -318,7 +331,10 @@
1024 {
1025 qDebug() << Q_FUNC_INFO;
1026 if (!m_transfer)
1027+ {
1028+ qWarning() << Q_FUNC_INFO << "Invalid transfer";
1029 return;
1030+ }
1031
1032 m_store = m_transfer->store();
1033 Q_EMIT storeChanged();
1034
1035=== modified file 'import/Ubuntu/Content/contenttransfer.h'
1036--- import/Ubuntu/Content/contenttransfer.h 2013-10-21 17:16:57 +0000
1037+++ import/Ubuntu/Content/contenttransfer.h 2014-03-19 13:45:37 +0000
1038@@ -51,8 +51,9 @@
1039 Finalized = com::ubuntu::content::Transfer::finalized
1040 };
1041 enum Direction {
1042- Import,
1043- Export
1044+ Import = com::ubuntu::content::Transfer::Import,
1045+ Export = com::ubuntu::content::Transfer::Export,
1046+ Share = com::ubuntu::content::Transfer::Share
1047 };
1048 enum SelectionType {
1049 Single = com::ubuntu::content::Transfer::SelectionType::single,
1050@@ -78,7 +79,7 @@
1051 Q_INVOKABLE void setStore(ContentStore *contentStore);
1052
1053 com::ubuntu::content::Transfer *transfer() const;
1054- void setTransfer(com::ubuntu::content::Transfer *transfer, Direction direction);
1055+ void setTransfer(com::ubuntu::content::Transfer *transfer);
1056
1057 void collectItems();
1058
1059
1060=== modified file 'import/Ubuntu/Content/qmlimportexporthandler.cpp'
1061--- import/Ubuntu/Content/qmlimportexporthandler.cpp 2013-08-23 15:51:35 +0000
1062+++ import/Ubuntu/Content/qmlimportexporthandler.cpp 2014-03-19 13:45:37 +0000
1063@@ -50,3 +50,11 @@
1064 Q_EMIT exportRequested(transfer);
1065 }
1066
1067+/*!
1068+ * \reimp
1069+ */
1070+void QmlImportExportHandler::handle_share(com::ubuntu::content::Transfer *transfer)
1071+{
1072+ qDebug() << Q_FUNC_INFO;
1073+ Q_EMIT shareRequested(transfer);
1074+}
1075
1076=== modified file 'import/Ubuntu/Content/qmlimportexporthandler.h'
1077--- import/Ubuntu/Content/qmlimportexporthandler.h 2013-08-23 15:51:35 +0000
1078+++ import/Ubuntu/Content/qmlimportexporthandler.h 2014-03-19 13:45:37 +0000
1079@@ -36,10 +36,12 @@
1080
1081 Q_INVOKABLE virtual void handle_import(com::ubuntu::content::Transfer *transfer);
1082 Q_INVOKABLE virtual void handle_export(com::ubuntu::content::Transfer *transfer);
1083+ Q_INVOKABLE virtual void handle_share(com::ubuntu::content::Transfer *transfer);
1084
1085 Q_SIGNALS:
1086 void importRequested(com::ubuntu::content::Transfer*);
1087 void exportRequested(com::ubuntu::content::Transfer*);
1088+ void shareRequested(com::ubuntu::content::Transfer*);
1089 };
1090
1091 #endif // COM_UBUNTU_QMLIMPORTEXPORTHANDLER_H_
1092
1093=== modified file 'include/com/ubuntu/content/hub.h'
1094--- include/com/ubuntu/content/hub.h 2013-09-10 14:11:37 +0000
1095+++ include/com/ubuntu/content/hub.h 2014-03-19 13:45:37 +0000
1096@@ -51,9 +51,14 @@
1097
1098 Q_INVOKABLE virtual void register_import_export_handler(ImportExportHandler* handler);
1099 Q_INVOKABLE virtual const Store* store_for_scope_and_type(Scope scope, Type type);
1100- Q_INVOKABLE virtual Peer default_peer_for_type(Type type);
1101- Q_INVOKABLE virtual QVector<Peer> known_peers_for_type(Type type);
1102- Q_INVOKABLE virtual Transfer* create_import_for_type_from_peer(Type type, Peer peer);
1103+ Q_INVOKABLE virtual Peer default_source_for_type(Type type);
1104+ Q_INVOKABLE virtual QVector<Peer> known_sources_for_type(Type type);
1105+ Q_INVOKABLE virtual QVector<Peer> known_destinations_for_type(Type type);
1106+ Q_INVOKABLE virtual QVector<Peer> known_shares_for_type(Type type);
1107+ Q_INVOKABLE virtual Transfer* create_import_from_peer(Peer peer);
1108+ Q_INVOKABLE virtual Transfer* create_export_to_peer(Peer peer);
1109+ Q_INVOKABLE virtual Transfer* create_share_to_peer(Peer peer);
1110+
1111
1112 Q_INVOKABLE virtual void quit();
1113
1114
1115=== modified file 'include/com/ubuntu/content/import_export_handler.h'
1116--- include/com/ubuntu/content/import_export_handler.h 2013-08-15 13:01:40 +0000
1117+++ include/com/ubuntu/content/import_export_handler.h 2014-03-19 13:45:37 +0000
1118@@ -38,6 +38,7 @@
1119
1120 Q_INVOKABLE virtual void handle_import(Transfer*) = 0;
1121 Q_INVOKABLE virtual void handle_export(Transfer*) = 0;
1122+ Q_INVOKABLE virtual void handle_share(Transfer*) = 0;
1123
1124 protected:
1125 ImportExportHandler(QObject* parent = nullptr);
1126
1127=== modified file 'include/com/ubuntu/content/peer.h'
1128--- include/com/ubuntu/content/peer.h 2013-10-01 16:55:39 +0000
1129+++ include/com/ubuntu/content/peer.h 2014-03-19 13:45:37 +0000
1130@@ -18,8 +18,10 @@
1131 #ifndef COM_UBUNTU_CONTENT_PEER_H_
1132 #define COM_UBUNTU_CONTENT_PEER_H_
1133
1134+#include <QtDBus>
1135 #include <QObject>
1136 #include <QSharedPointer>
1137+#include <QImage>
1138
1139 namespace com
1140 {
1141@@ -30,12 +32,13 @@
1142 class Peer : public QObject
1143 {
1144 Q_OBJECT
1145- Q_PROPERTY(QString id READ id())
1146- Q_PROPERTY(QString name READ name())
1147+ Q_PROPERTY(QString id READ id)
1148+ Q_PROPERTY(QString name READ name WRITE setName)
1149+ Q_PROPERTY(QImage icon READ icon WRITE setIcon)
1150+ Q_PROPERTY(QString iconName READ iconName WRITE setIconName)
1151
1152 public:
1153 static const Peer& unknown();
1154-
1155 Peer(const QString& id = QString(), QObject* parent = nullptr);
1156 Peer(const Peer& rhs);
1157 virtual ~Peer();
1158@@ -44,7 +47,12 @@
1159 bool operator==(const Peer& rhs) const;
1160
1161 Q_INVOKABLE virtual const QString& id() const;
1162- Q_INVOKABLE virtual QString name();
1163+ Q_INVOKABLE virtual QString name() const;
1164+ Q_INVOKABLE void setName(const QString&);
1165+ Q_INVOKABLE virtual QImage icon() const;
1166+ Q_INVOKABLE void setIcon(const QImage&);
1167+ Q_INVOKABLE virtual QString iconName() const;
1168+ Q_INVOKABLE void setIconName(const QString&);
1169
1170 private:
1171 struct Private;
1172@@ -54,4 +62,14 @@
1173 }
1174 }
1175
1176+Q_DECL_EXPORT
1177+QDBusArgument &operator<<(QDBusArgument &argument,
1178+ const com::ubuntu::content::Peer &peer);
1179+
1180+Q_DECL_EXPORT
1181+const QDBusArgument &operator>>(const QDBusArgument &argument,
1182+ com::ubuntu::content::Peer &peer);
1183+
1184+Q_DECLARE_METATYPE(com::ubuntu::content::Peer)
1185+
1186 #endif // COM_UBUNTU_CONTENT_PEER_H_
1187
1188=== modified file 'include/com/ubuntu/content/transfer.h'
1189--- include/com/ubuntu/content/transfer.h 2013-10-01 16:55:39 +0000
1190+++ include/com/ubuntu/content/transfer.h 2014-03-19 13:45:37 +0000
1191@@ -52,11 +52,13 @@
1192 Q_OBJECT
1193 Q_ENUMS(State)
1194 Q_ENUMS(SelectionType)
1195+ Q_ENUMS(Direction)
1196 Q_PROPERTY(int id READ id)
1197 Q_PROPERTY(State state READ state NOTIFY stateChanged)
1198 Q_PROPERTY(QVector<Item> items READ collect WRITE charge)
1199 Q_PROPERTY(Store store READ store NOTIFY storeChanged)
1200 Q_PROPERTY(SelectionType selectionType READ selectionType WRITE setSelectionType NOTIFY selectionTypeChanged)
1201+ Q_PROPERTY(Direction direction READ direction)
1202
1203 public:
1204 enum State
1205@@ -76,6 +78,13 @@
1206 multiple
1207 };
1208
1209+ enum Direction
1210+ {
1211+ Import,
1212+ Export,
1213+ Share
1214+ };
1215+
1216 Transfer(const Transfer&) = delete;
1217 virtual ~Transfer();
1218
1219@@ -84,6 +93,7 @@
1220 Q_INVOKABLE virtual int id() const;
1221 Q_INVOKABLE virtual State state() const;
1222 Q_INVOKABLE virtual SelectionType selectionType() const;
1223+ Q_INVOKABLE virtual Direction direction() const;
1224 Q_INVOKABLE virtual bool start();
1225 Q_INVOKABLE virtual bool abort();
1226 Q_INVOKABLE virtual bool finalize();
1227
1228=== modified file 'include/com/ubuntu/content/type.h'
1229--- include/com/ubuntu/content/type.h 2013-12-10 15:59:15 +0000
1230+++ include/com/ubuntu/content/type.h 2014-03-19 13:45:37 +0000
1231@@ -30,6 +30,7 @@
1232 namespace detail
1233 {
1234 class Service;
1235+class Hook;
1236 }
1237 class Type : public QObject
1238 {
1239@@ -59,6 +60,7 @@
1240 protected:
1241 friend struct Known;
1242 friend class detail::Service;
1243+ friend class detail::Hook;
1244
1245 explicit Type(const QString&, QObject* = nullptr);
1246
1247
1248=== modified file 'libcontent-hub.pc.in'
1249--- libcontent-hub.pc.in 2013-09-30 21:28:46 +0000
1250+++ libcontent-hub.pc.in 2014-03-19 13:45:37 +0000
1251@@ -1,8 +1,11 @@
1252 prefix=@prefix@
1253 exec_prefix=@exec_prefix@
1254 libdir=@libdir@
1255+includedir=${prefix}/include
1256
1257 Name: @pkg-name@
1258 Description: content sharing/picking library
1259 Version: @CONTENT_HUB_VERSION@
1260 Libs: -L${libdir} -lcontent-hub
1261+Cflags: -I${includedir}
1262+Requires: Qt5DBus
1263
1264=== modified file 'src/com/ubuntu/content/CMakeLists.txt'
1265--- src/com/ubuntu/content/CMakeLists.txt 2013-12-06 12:38:33 +0000
1266+++ src/com/ubuntu/content/CMakeLists.txt 2014-03-19 13:45:37 +0000
1267@@ -20,6 +20,7 @@
1268 ${CMAKE_CURRENT_BINARY_DIR}
1269 ${CMAKE_SOURCE_DIR}/src
1270 ${CMAKE_SOURCE_DIR}
1271+ ${CMAKE_SOURCE_DIR}/include
1272 ${GLIB_INCLUDE_DIRS}
1273 ${GIO_INCLUDE_DIRS}
1274 ${NIH_INCLUDE_DIRS}
1275@@ -91,7 +92,7 @@
1276 AUTOMOC TRUE
1277 )
1278
1279-qt5_use_modules(content-hub Core DBus)
1280+qt5_use_modules(content-hub Core DBus Gui)
1281
1282 target_link_libraries(content-hub
1283 ${UPSTART_LAUNCH_LDFLAGS}
1284
1285=== modified file 'src/com/ubuntu/content/detail/app_manager.cpp'
1286--- src/com/ubuntu/content/detail/app_manager.cpp 2013-12-06 12:36:31 +0000
1287+++ src/com/ubuntu/content/detail/app_manager.cpp 2014-03-19 13:45:37 +0000
1288@@ -17,14 +17,17 @@
1289 #include "app_manager.h"
1290
1291 #include <upstart-app-launch.h>
1292+#include <QDebug>
1293
1294 namespace cucd = com::ubuntu::content::detail;
1295
1296 /*!
1297 * \reimp
1298 */
1299+
1300 bool cucd::AppManager::invoke_application(const std::string &app_id)
1301 {
1302+ qDebug() << Q_FUNC_INFO << "APP_ID:" << app_id.c_str();
1303 gchar ** uris = NULL;
1304 gboolean ok = upstart_app_launch_start_application(app_id.c_str(), (const gchar * const *)uris);
1305 return static_cast<bool>(ok);
1306@@ -35,6 +38,8 @@
1307 */
1308 bool cucd::AppManager::stop_application(const std::string &app_id)
1309 {
1310+ qDebug() << Q_FUNC_INFO << "APP_ID:" << app_id.c_str();
1311+
1312 gboolean ok = upstart_app_launch_stop_application(app_id.c_str());
1313 return static_cast<bool>(ok);
1314 }
1315
1316=== modified file 'src/com/ubuntu/content/detail/com.ubuntu.content.Handler.xml'
1317--- src/com/ubuntu/content/detail/com.ubuntu.content.Handler.xml 2013-08-22 12:48:30 +0000
1318+++ src/com/ubuntu/content/detail/com.ubuntu.content.Handler.xml 2014-03-19 13:45:37 +0000
1319@@ -6,5 +6,8 @@
1320 <method name="HandleExport">
1321 <arg name="transfer" type="o" direction="in"/>
1322 </method>
1323+ <method name="HandleShare">
1324+ <arg name="transfer" type="o" direction="in"/>
1325+ </method>
1326 </interface>
1327 </node>
1328
1329=== modified file 'src/com/ubuntu/content/detail/com.ubuntu.content.Service.xml'
1330--- src/com/ubuntu/content/detail/com.ubuntu.content.Service.xml 2013-09-10 14:11:37 +0000
1331+++ src/com/ubuntu/content/detail/com.ubuntu.content.Service.xml 2014-03-19 13:45:37 +0000
1332@@ -2,23 +2,38 @@
1333 <interface name="com.ubuntu.content.dbus.Service">
1334 <method name="Quit">
1335 </method>
1336- <method name="DefaultPeerForType">
1337- <annotation name="com.trolltech.QtDBus.QtTypeName.In1" value="QVariantMap"/>
1338- <arg name="type_id" type="s" direction="in" />
1339- <arg name="peer_id" type="s" direction="out" />
1340- </method>
1341- <method name="KnownPeersForType">
1342- <arg name="type_id" type="s" direction="in" />
1343- <arg name="peer_ids" type="as" direction="out" />
1344- </method>
1345- <method name="CreateImportForTypeFromPeer">
1346- <arg name="type_id" type="s" direction="in" />
1347+ <method name="DefaultSourceForType">
1348+ <arg name="type_id" type="s" direction="in" />
1349+ <arg name="peer" type="v" direction="out" />
1350+ </method>
1351+ <method name="KnownSourcesForType">
1352+ <arg name="type_id" type="s" direction="in" />
1353+ <arg name="peers" type="av" direction="out" />
1354+ </method>
1355+ <method name="KnownDestinationsForType">
1356+ <arg name="type_id" type="s" direction="in" />
1357+ <arg name="peers" type="av" direction="out" />
1358+ </method>
1359+ <method name="KnownSharesForType">
1360+ <arg name="type_id" type="s" direction="in" />
1361+ <arg name="peers" type="av" direction="out" />
1362+ </method>
1363+ <method name="CreateImportFromPeer">
1364+ <arg name="peer_id" type="s" direction="in" />
1365+ <arg name="app_id" type="s" direction="in" />
1366+ <arg name="transfer_object" type="o" direction="out" />
1367+ </method>
1368+ <method name="CreateExportToPeer">
1369+ <arg name="peer_id" type="s" direction="in" />
1370+ <arg name="app_id" type="s" direction="in" />
1371+ <arg name="transfer_object" type="o" direction="out" />
1372+ </method>
1373+ <method name="CreateShareToPeer">
1374 <arg name="peer_id" type="s" direction="in" />
1375 <arg name="app_id" type="s" direction="in" />
1376 <arg name="transfer_object" type="o" direction="out" />
1377 </method>
1378 <method name="RegisterImportExportHandler">
1379- <arg name="type_id" type="s" direction="in" />
1380 <arg name="peer_id" type="s" direction="in" />
1381 <arg name="handler_object" type="o" direction="in" />
1382 </method>
1383
1384=== modified file 'src/com/ubuntu/content/detail/com.ubuntu.content.Transfer.xml'
1385--- src/com/ubuntu/content/detail/com.ubuntu.content.Transfer.xml 2013-10-01 16:55:39 +0000
1386+++ src/com/ubuntu/content/detail/com.ubuntu.content.Transfer.xml 2014-03-19 13:45:37 +0000
1387@@ -41,5 +41,8 @@
1388 <signal name="SelectionTypeChanged">
1389 <arg name="selection_type" type="i"/>
1390 </signal>
1391+ <method name="Direction">
1392+ <arg name="direction" type="i" direction="out" />
1393+ </method>
1394 </interface>
1395 </node>
1396
1397=== modified file 'src/com/ubuntu/content/detail/handler.cpp'
1398--- src/com/ubuntu/content/detail/handler.cpp 2013-09-09 18:07:14 +0000
1399+++ src/com/ubuntu/content/detail/handler.cpp 2014-03-19 13:45:37 +0000
1400@@ -21,6 +21,7 @@
1401 #include "utils.cpp"
1402
1403 #include <QObject>
1404+#include <QDebug>
1405
1406 namespace cucd = com::ubuntu::content::detail;
1407 namespace cuc = com::ubuntu::content;
1408@@ -48,11 +49,13 @@
1409 m_handler = handler;
1410 }
1411
1412-cucd::Handler::~Handler() {}
1413+cucd::Handler::~Handler() {
1414+ delete m_handler;
1415+}
1416
1417 void cucd::Handler::HandleImport(const QDBusObjectPath& transfer)
1418 {
1419- qDebug() << Q_FUNC_INFO;
1420+ qDebug() << Q_FUNC_INFO << transfer.path();
1421 cuc::Transfer* t = cuc::Transfer::Private::make_transfer(transfer, this);
1422
1423 qDebug() << Q_FUNC_INFO << "State:" << t->state();
1424@@ -62,7 +65,7 @@
1425
1426 void cucd::Handler::HandleExport(const QDBusObjectPath& transfer)
1427 {
1428- qDebug() << Q_FUNC_INFO;
1429+ qDebug() << Q_FUNC_INFO << transfer.path();
1430 cuc::Transfer* t = cuc::Transfer::Private::make_transfer(transfer, this);
1431
1432 qDebug() << Q_FUNC_INFO << "State:" << t->state();
1433@@ -72,3 +75,15 @@
1434 m_handler->handle_export(t);
1435 }
1436 }
1437+
1438+void cucd::Handler::HandleShare(const QDBusObjectPath& transfer)
1439+{
1440+ qDebug() << Q_FUNC_INFO;
1441+ cuc::Transfer* t = cuc::Transfer::Private::make_transfer(transfer, this);
1442+
1443+ qDebug() << Q_FUNC_INFO << "State:" << t->state();
1444+ if (t->state() == cuc::Transfer::charged)
1445+ {
1446+ m_handler->handle_share(t);
1447+ }
1448+}
1449
1450=== modified file 'src/com/ubuntu/content/detail/handler.h'
1451--- src/com/ubuntu/content/detail/handler.h 2013-09-06 13:18:05 +0000
1452+++ src/com/ubuntu/content/detail/handler.h 2014-03-19 13:45:37 +0000
1453@@ -48,6 +48,7 @@
1454 public Q_SLOTS:
1455 void HandleImport(const QDBusObjectPath &transfer);
1456 void HandleExport(const QDBusObjectPath &transfer);
1457+ void HandleShare(const QDBusObjectPath &transfer);
1458
1459 private:
1460 struct Private;
1461
1462=== modified file 'src/com/ubuntu/content/detail/peer_registry.h'
1463--- src/com/ubuntu/content/detail/peer_registry.h 2013-09-25 03:14:53 +0000
1464+++ src/com/ubuntu/content/detail/peer_registry.h 2014-03-19 13:45:37 +0000
1465@@ -40,12 +40,15 @@
1466
1467 PeerRegistry& operator=(const PeerRegistry&) = delete;
1468
1469- virtual Peer default_peer_for_type(Type) = 0;
1470- virtual void enumerate_known_peers_for_type(Type, const std::function<void(const Peer&)>& for_each) = 0;
1471+ virtual Peer default_source_for_type(Type) = 0;
1472 virtual void enumerate_known_peers(const std::function<void(const Peer&)>& for_each) = 0;
1473-
1474- virtual bool install_default_peer_for_type(Type, Peer) = 0;
1475- virtual bool install_peer_for_type(Type, Peer) = 0;
1476+ virtual void enumerate_known_sources_for_type(Type, const std::function<void(const Peer&)>& for_each) = 0;
1477+ virtual void enumerate_known_destinations_for_type(Type, const std::function<void(const Peer&)>& for_each) = 0;
1478+ virtual void enumerate_known_shares_for_type(Type, const std::function<void(const Peer&)>& for_each) = 0;
1479+ virtual bool install_default_source_for_type(Type, Peer) = 0;
1480+ virtual bool install_source_for_type(Type, Peer) = 0;
1481+ virtual bool install_destination_for_type(Type, Peer) = 0;
1482+ virtual bool install_share_for_type(Type, Peer) = 0;
1483 virtual bool remove_peer(Peer peer) = 0;
1484
1485
1486
1487=== modified file 'src/com/ubuntu/content/detail/service.cpp'
1488--- src/com/ubuntu/content/detail/service.cpp 2013-10-10 15:00:36 +0000
1489+++ src/com/ubuntu/content/detail/service.cpp 2014-03-19 13:45:37 +0000
1490@@ -22,14 +22,13 @@
1491 #include "transfer.h"
1492 #include "transferadaptor.h"
1493 #include "utils.cpp"
1494-
1495-#include "handler.h"
1496 #include "ContentHandlerInterface.h"
1497
1498 #include <com/ubuntu/content/peer.h>
1499 #include <com/ubuntu/content/type.h>
1500 #include <com/ubuntu/content/transfer.h>
1501
1502+#include <QDBusMetaType>
1503 #include <QCache>
1504 #include <QCoreApplication>
1505 #include <QDebug>
1506@@ -42,6 +41,19 @@
1507 namespace cucd = com::ubuntu::content::detail;
1508 namespace cuc = com::ubuntu::content;
1509
1510+struct cucd::Service::RegHandler
1511+{
1512+ RegHandler(QString id, QString service, cuc::dbus::Handler* handler) : id(id),
1513+ service(service),
1514+ handler(handler)
1515+ {
1516+ }
1517+
1518+ QString id;
1519+ QString service;
1520+ cuc::dbus::Handler* handler;
1521+};
1522+
1523 struct cucd::Service::Private : public QObject
1524 {
1525 Private(QDBusConnection connection,
1526@@ -58,7 +70,9 @@
1527 QDBusConnection connection;
1528 QSharedPointer<cucd::PeerRegistry> registry;
1529 QSet<cucd::Transfer*> active_transfers;
1530+ QSet<RegHandler*> handlers;
1531 QSharedPointer<cua::ApplicationManager> app_manager;
1532+
1533 };
1534
1535 cucd::Service::Service(QDBusConnection connection, const QSharedPointer<cucd::PeerRegistry>& peer_registry,
1536@@ -69,11 +83,13 @@
1537 {
1538 assert(!peer_registry.isNull());
1539
1540- m_watcher->setWatchMode(QDBusServiceWatcher::WatchForRegistration);
1541+ qDBusRegisterMetaType<cuc::Peer>();
1542+
1543+ m_watcher->setWatchMode(QDBusServiceWatcher::WatchForUnregistration);
1544 m_watcher->setConnection(d->connection);
1545- QObject::connect(m_watcher, SIGNAL(serviceRegistered(const QString&)),
1546+ QObject::connect(m_watcher, SIGNAL(serviceUnregistered(const QString&)),
1547 this,
1548- SLOT(handler_registered(const QString&)));
1549+ SLOT(handler_unregistered(const QString&)));
1550 }
1551
1552 cucd::Service::~Service()
1553@@ -86,172 +102,374 @@
1554 }
1555 }
1556
1557-void cucd::Service::handler_registered(const QString& name)
1558-{
1559- qDebug() << Q_FUNC_INFO << name;
1560- Q_FOREACH (cucd::Transfer *t, d->active_transfers)
1561- {
1562- if (handler_address(t->source()) == name)
1563- {
1564- qDebug() << Q_FUNC_INFO << "Found source:" << name;
1565- cuc::dbus::Handler *h = new cuc::dbus::Handler(
1566- name,
1567- handler_path(t->source()),
1568- QDBusConnection::sessionBus(),
1569- 0);
1570- if (h->isValid())
1571- h->HandleExport(QDBusObjectPath{t->export_path()});
1572- }
1573- else if (handler_address(t->destination()) == name)
1574- {
1575- qDebug() << Q_FUNC_INFO << "Found destination:" << name;
1576- cuc::dbus::Handler *h = new cuc::dbus::Handler(
1577- name,
1578- handler_path(t->destination()),
1579- QDBusConnection::sessionBus(),
1580- 0);
1581- if (h->isValid())
1582- h->HandleImport(QDBusObjectPath{t->import_path()});
1583- }
1584- }
1585-}
1586-
1587 void cucd::Service::Quit()
1588 {
1589 QCoreApplication::instance()->quit();
1590 }
1591
1592-QStringList cucd::Service::KnownPeersForType(const QString& type_id)
1593-{
1594- QStringList result;
1595-
1596- d->registry->enumerate_known_peers_for_type(
1597- Type(type_id),
1598- [&result](const Peer& peer)
1599- {
1600- result.append(peer.id());
1601- });
1602-
1603- return result;
1604-}
1605-
1606-QString cucd::Service::DefaultPeerForType(const QString& type_id)
1607-{
1608- auto peer = d->registry->default_peer_for_type(Type(type_id));
1609-
1610- return peer.id();
1611-}
1612-
1613-void cucd::Service::connect_export_handler(const QString& peer_id, const QString& transfer)
1614-{
1615- qDebug() << Q_FUNC_INFO;
1616-
1617- cuc::dbus::Handler *h = new cuc::dbus::Handler(
1618- handler_address(peer_id),
1619- handler_path(peer_id),
1620- QDBusConnection::sessionBus(),
1621- 0);
1622-
1623- qDebug() << Q_FUNC_INFO << "h->isValid:" << h->isValid();
1624- if (h->isValid() && (not transfer.isEmpty()))
1625- h->HandleExport(QDBusObjectPath{transfer});
1626-}
1627-
1628-void cucd::Service::connect_import_handler(const QString& peer_id, const QString& transfer)
1629-{
1630- qDebug() << Q_FUNC_INFO;
1631-
1632- cuc::dbus::Handler *h = new cuc::dbus::Handler(
1633- handler_address(peer_id),
1634- handler_path(peer_id),
1635- QDBusConnection::sessionBus(),
1636- 0);
1637-
1638- qDebug() << Q_FUNC_INFO << "h->isValid:" << h->isValid();
1639- if (h->isValid() && (not transfer.isEmpty()))
1640- h->HandleImport(QDBusObjectPath{transfer});
1641-}
1642-
1643-QDBusObjectPath cucd::Service::CreateImportForTypeFromPeer(const QString& type_id, const QString& peer_id, const QString& dest_id)
1644-{
1645- qDebug() << Q_FUNC_INFO;
1646+QVariantList cucd::Service::KnownSourcesForType(const QString& type_id)
1647+{
1648+ QVariantList result;
1649+
1650+ d->registry->enumerate_known_sources_for_type(
1651+ Type(type_id),
1652+ [&result](const Peer& peer)
1653+ {
1654+ result.append(QVariant::fromValue(peer));
1655+ });
1656+
1657+ return result;
1658+}
1659+
1660+QVariantList cucd::Service::KnownDestinationsForType(const QString& type_id)
1661+{
1662+ QVariantList result;
1663+
1664+ d->registry->enumerate_known_destinations_for_type(
1665+ Type(type_id),
1666+ [&result](const Peer& peer)
1667+ {
1668+ result.append(QVariant::fromValue(peer));
1669+ });
1670+
1671+ return result;
1672+}
1673+
1674+QVariantList cucd::Service::KnownSharesForType(const QString& type_id)
1675+{
1676+ QVariantList result;
1677+
1678+ d->registry->enumerate_known_shares_for_type(
1679+ Type(type_id),
1680+ [&result](const Peer& peer)
1681+ {
1682+ result.append(QVariant::fromValue(peer));
1683+ });
1684+
1685+ return result;
1686+}
1687+
1688+QDBusVariant cucd::Service::DefaultSourceForType(const QString& type_id)
1689+{
1690+ cuc::Peer peer = d->registry->default_source_for_type(Type(type_id));
1691+
1692+ return QDBusVariant(QVariant::fromValue(peer));
1693+}
1694+
1695+QDBusObjectPath cucd::Service::CreateImportFromPeer(const QString& peer_id, const QString& app_id)
1696+{
1697+ qDebug() << Q_FUNC_INFO;
1698+ QString dest_id = app_id;
1699+ if (dest_id.isEmpty())
1700+ {
1701+ qDebug() << Q_FUNC_INFO << "APP_ID isnt' set, attempting to get it from AppArmor";
1702+ dest_id = aa_profile(this->message().service());
1703+ }
1704+ return CreateTransfer(dest_id, peer_id, cuc::Transfer::Import);
1705+}
1706+
1707+bool cucd::Service::should_cancel (int st)
1708+{
1709+ qDebug() << Q_FUNC_INFO << "State:" << st;
1710+
1711+ return (st != cuc::Transfer::finalized
1712+ && st != cuc::Transfer::collected
1713+ && st != cuc::Transfer::aborted);
1714+}
1715+
1716+QDBusObjectPath cucd::Service::CreateExportToPeer(const QString& peer_id, const QString& app_id)
1717+{
1718+ qDebug() << Q_FUNC_INFO;
1719+ QString src_id = app_id;
1720+ if (src_id.isEmpty())
1721+ {
1722+ qDebug() << Q_FUNC_INFO << "APP_ID isnt' set, attempting to get it from AppArmor";
1723+ src_id = aa_profile(this->message().service());
1724+ }
1725+ return CreateTransfer(peer_id, src_id, cuc::Transfer::Export);
1726+}
1727+
1728+QDBusObjectPath cucd::Service::CreateShareToPeer(const QString& peer_id, const QString& app_id)
1729+{
1730+ qDebug() << Q_FUNC_INFO;
1731+ QString src_id = app_id;
1732+ if (src_id.isEmpty())
1733+ {
1734+ qDebug() << Q_FUNC_INFO << "APP_ID isnt' set, attempting to get it from AppArmor";
1735+ src_id = aa_profile(this->message().service());
1736+ }
1737+ return CreateTransfer(peer_id, src_id, cuc::Transfer::Share);
1738+}
1739+
1740+QDBusObjectPath cucd::Service::CreateTransfer(const QString& dest_id, const QString& src_id, int dir)
1741+{
1742+ qDebug() << Q_FUNC_INFO << "DEST:" << dest_id << "SRC:" << src_id << "DIRECTION:" << dir;
1743
1744 static size_t import_counter{0}; import_counter++;
1745
1746- QString app_id = dest_id;
1747- if (app_id.isEmpty())
1748- {
1749- qDebug() << Q_FUNC_INFO << "APP_ID isnt' set, attempting to get it from AppArmor";
1750- app_id = aa_profile(this->message().service());
1751- }
1752-
1753- qDebug() << Q_FUNC_INFO << "APP_ID:" << app_id;
1754-
1755 QUuid uuid{QUuid::createUuid()};
1756
1757- auto transfer = new cucd::Transfer(import_counter, peer_id, app_id, this);
1758+ Q_FOREACH (cucd::Transfer *t, d->active_transfers)
1759+ {
1760+ if (t->destination() == dest_id || t->source() == src_id)
1761+ {
1762+ qDebug() << Q_FUNC_INFO << "Found transfer for peer_id:" << src_id;
1763+ if (should_cancel(t->State()))
1764+ {
1765+ qDebug() << Q_FUNC_INFO << "Aborting active transfer:" << t->Id();
1766+ t->Abort();
1767+ }
1768+ }
1769+ }
1770+
1771+ auto transfer = new cucd::Transfer(import_counter, src_id, dest_id, dir, this);
1772 new TransferAdaptor(transfer);
1773 d->active_transfers.insert(transfer);
1774
1775 auto destination = transfer->import_path();
1776 auto source = transfer->export_path();
1777- if (not d->connection.registerObject(destination, transfer))
1778- qDebug() << "Problem registering object for path: " << destination;
1779- d->connection.registerObject(source, transfer);
1780+ if (not d->connection.registerObject(source, transfer))
1781+ qDebug() << "Problem registering object for path: " << source;
1782+ d->connection.registerObject(destination, transfer);
1783
1784 qDebug() << "Created transfer " << source << " -> " << destination;
1785
1786- connect(transfer, SIGNAL(StateChanged(int)), this, SLOT(handle_transfer(int)));
1787-
1788- /* watch for handlers */
1789- m_watcher->addWatchedService(handler_address(peer_id));
1790- qDebug() << Q_FUNC_INFO << "Watches:" << m_watcher->watchedServices();
1791- this->connect_export_handler(peer_id, source);
1792- this->connect_import_handler(app_id, destination);
1793-
1794- Q_UNUSED(type_id);
1795-
1796- return QDBusObjectPath{destination};
1797-}
1798-
1799-void cucd::Service::handle_transfer(int state)
1800+ // Content flow is different for import
1801+ if (dir == cuc::Transfer::Import)
1802+ {
1803+ connect(transfer, SIGNAL(StateChanged(int)), this, SLOT(handle_imports(int)));
1804+ return QDBusObjectPath{destination};
1805+ }
1806+
1807+ connect(transfer, SIGNAL(StateChanged(int)), this, SLOT(handle_exports(int)));
1808+ return QDBusObjectPath{source};
1809+}
1810+
1811+void cucd::Service::handle_imports(int state)
1812+{
1813+ qDebug() << Q_FUNC_INFO << state;
1814+ cucd::Transfer *transfer = static_cast<cucd::Transfer*>(sender());
1815+ qDebug() << Q_FUNC_INFO << "State: " << transfer->State() << "Id:" << transfer->Id();
1816+
1817+ if (state == cuc::Transfer::initiated)
1818+ {
1819+ qDebug() << Q_FUNC_INFO << "initiated";
1820+ if (d->app_manager->is_application_started(transfer->source().toStdString()))
1821+ transfer->SetSourceStartedByContentHub(false);
1822+ else
1823+ transfer->SetSourceStartedByContentHub(true);
1824+
1825+ Q_FOREACH (RegHandler *r, d->handlers)
1826+ {
1827+ qDebug() << Q_FUNC_INFO << "ID:" << r->id << "Handler: " << r->service << "Transfer: " << transfer->source();
1828+ if (r->id == transfer->source())
1829+ {
1830+ qDebug() << Q_FUNC_INFO << "Found handler for initiated transfer" << r->id;
1831+ if (r->handler->isValid())
1832+ r->handler->HandleExport(QDBusObjectPath{transfer->export_path()});
1833+ else
1834+ qDebug() << Q_FUNC_INFO << "Handler invalid";
1835+ }
1836+ }
1837+
1838+ d->app_manager->invoke_application(transfer->source().toStdString());
1839+ }
1840+
1841+ if (state == cuc::Transfer::charged)
1842+ {
1843+ qDebug() << Q_FUNC_INFO << "Charged";
1844+ if (transfer->WasSourceStartedByContentHub())
1845+ d->app_manager->stop_application(transfer->source().toStdString());
1846+
1847+ d->app_manager->invoke_application(transfer->destination().toStdString());
1848+
1849+ Q_FOREACH (RegHandler *r, d->handlers)
1850+ {
1851+ qDebug() << Q_FUNC_INFO << "ID:" << r->id << "Handler: " << r->service << "Transfer: " << transfer->destination();
1852+ if (r->id == transfer->destination())
1853+ {
1854+ qDebug() << Q_FUNC_INFO << "Found handler for charged transfer" << r->id;
1855+ if (r->handler->isValid())
1856+ r->handler->HandleImport(QDBusObjectPath{transfer->import_path()});
1857+ }
1858+ }
1859+ }
1860+
1861+ if (state == cuc::Transfer::aborted)
1862+ {
1863+ if (transfer->WasSourceStartedByContentHub())
1864+ {
1865+ bool shouldStop = true;
1866+ Q_FOREACH (cucd::Transfer *t, d->active_transfers)
1867+ {
1868+ if (t->Id() != transfer->Id())
1869+ {
1870+ if ((t->source() == transfer->source()) || (t->destination() == transfer->destination()))
1871+ {
1872+ qDebug() << Q_FUNC_INFO << "Peer has pending transfers:" << t->Id();
1873+ shouldStop = false;
1874+ }
1875+ }
1876+ }
1877+ if (shouldStop)
1878+ {
1879+ d->app_manager->stop_application(transfer->source().toStdString());
1880+ d->app_manager->invoke_application(transfer->destination().toStdString());
1881+ }
1882+ }
1883+ }
1884+}
1885+
1886+void cucd::Service::handle_exports(int state)
1887 {
1888 qDebug() << Q_FUNC_INFO;
1889 cucd::Transfer *transfer = static_cast<cucd::Transfer*>(sender());
1890
1891+ qDebug() << Q_FUNC_INFO << "STATE:" << transfer->State();
1892+
1893+
1894 if (state == cuc::Transfer::initiated)
1895 {
1896 qDebug() << Q_FUNC_INFO << "Initiated";
1897- if (d->app_manager->is_application_started(transfer->source().toStdString()))
1898+ transfer->Handled();
1899+ }
1900+
1901+ if (state == cuc::Transfer::charged)
1902+ {
1903+ qDebug() << Q_FUNC_INFO << "Charged";
1904+ if (d->app_manager->is_application_started(transfer->destination().toStdString()))
1905 transfer->SetSourceStartedByContentHub(false);
1906 else
1907 transfer->SetSourceStartedByContentHub(true);
1908
1909+ d->app_manager->invoke_application(transfer->destination().toStdString());
1910+
1911+ Q_FOREACH (RegHandler *r, d->handlers)
1912+ {
1913+ qDebug() << "Handler: " << r->service << "Transfer: " << transfer->destination();
1914+ if (r->id == transfer->destination())
1915+ {
1916+ qDebug() << "Found handler for charged transfer" << r->id;
1917+ if (transfer->Direction() == cuc::Transfer::Share && r->handler->isValid())
1918+ r->handler->HandleShare(QDBusObjectPath{transfer->import_path()});
1919+ else if (r->handler->isValid())
1920+ r->handler->HandleImport(QDBusObjectPath{transfer->import_path()});
1921+ }
1922+ }
1923+ }
1924+
1925+ if (state == cuc::Transfer::finalized)
1926+ {
1927+ qDebug() << Q_FUNC_INFO << "Finalized";
1928+ if (transfer->WasSourceStartedByContentHub())
1929+ d->app_manager->stop_application(transfer->destination().toStdString());
1930+
1931 d->app_manager->invoke_application(transfer->source().toStdString());
1932- this->connect_export_handler(transfer->source(), transfer->export_path());
1933- }
1934-
1935- if (state == cuc::Transfer::charged)
1936- {
1937- qDebug() << Q_FUNC_INFO << "Charged";
1938- d->app_manager->invoke_application(transfer->destination().toStdString());
1939-
1940- if (transfer->WasSourceStartedByContentHub())
1941- d->app_manager->stop_application(transfer->source().toStdString());
1942-
1943- this->connect_import_handler(transfer->destination(), transfer->import_path());
1944 }
1945
1946 if (state == cuc::Transfer::aborted)
1947 {
1948- d->app_manager->invoke_application(transfer->destination().toStdString());
1949-
1950+ qDebug() << Q_FUNC_INFO << "Aborted";
1951 if (transfer->WasSourceStartedByContentHub())
1952- d->app_manager->stop_application(transfer->source().toStdString());
1953- }
1954-}
1955-
1956-void cucd::Service::RegisterImportExportHandler(const QString& /*type_id*/, const QString& peer_id, const QDBusObjectPath& handler)
1957-{
1958- qDebug() << Q_FUNC_INFO << peer_id << ":" << handler.path();
1959+ {
1960+ bool shouldStop = true;
1961+ Q_FOREACH (cucd::Transfer *t, d->active_transfers)
1962+ {
1963+ if (t->Id() != transfer->Id())
1964+ {
1965+ if ((t->source() == transfer->source()) || (t->destination() == transfer->destination()))
1966+ {
1967+ qDebug() << Q_FUNC_INFO << "Peer has pending transfers:" << t->Id();
1968+ shouldStop = false;
1969+ }
1970+ }
1971+ }
1972+ if (shouldStop)
1973+ {
1974+ d->app_manager->stop_application(transfer->destination().toStdString());
1975+ d->app_manager->invoke_application(transfer->source().toStdString());
1976+ }
1977+ }
1978+ }
1979+}
1980+
1981+void cucd::Service::handler_unregistered(const QString& s)
1982+{
1983+ qDebug() << Q_FUNC_INFO << s;
1984+
1985+ if (d->handlers.isEmpty())
1986+ return;
1987+
1988+ Q_FOREACH (RegHandler *r, d->handlers)
1989+ {
1990+ qDebug() << "Handler: " << r->id;
1991+ if (r->service == s)
1992+ {
1993+ qDebug() << "Found match for " << r->id;
1994+ d->handlers.remove(r);
1995+ m_watcher->removeWatchedService(s);
1996+ delete r;
1997+ }
1998+ }
1999+}
2000+
2001+void cucd::Service::RegisterImportExportHandler(const QString& peer_id, const QDBusObjectPath& handler)
2002+{
2003+ qDebug() << Q_FUNC_INFO << peer_id;
2004+ bool exists = false;
2005+ RegHandler* r;
2006+ Q_FOREACH (RegHandler *rh, d->handlers)
2007+ {
2008+ qDebug() << "Handler: " << rh->id;
2009+ if (rh->id == peer_id)
2010+ {
2011+ qDebug() << "Found existing handler for " << rh->id;
2012+ exists = true;
2013+ r = rh;
2014+ }
2015+ }
2016+
2017+ if (!exists)
2018+ {
2019+ r = new RegHandler{peer_id,
2020+ this->message().service(),
2021+ new cuc::dbus::Handler(
2022+ this->message().service(),
2023+ handler.path(),
2024+ QDBusConnection::sessionBus(),
2025+ 0)};
2026+ d->handlers.insert(r);
2027+ m_watcher->addWatchedService(r->service);
2028+ }
2029+
2030+ qDebug() << Q_FUNC_INFO << r->id;
2031+
2032+ Q_FOREACH (cucd::Transfer *t, d->active_transfers)
2033+ {
2034+ qDebug() << Q_FUNC_INFO << "SOURCE: " << t->source() << "DEST:" << t->destination() << "STATE:" << t->State();
2035+ if ((t->source() == peer_id) && (t->State() == cuc::Transfer::initiated))
2036+ {
2037+ qDebug() << Q_FUNC_INFO << "Found source:" << peer_id << "Direction:" << t->Direction();
2038+ if (t->Direction() == cuc::Transfer::Import)
2039+ {
2040+ if (r->handler->isValid())
2041+ r->handler->HandleExport(QDBusObjectPath{t->export_path()});
2042+ }
2043+ }
2044+ else if ((t->destination() == peer_id) && (t->State() == cuc::Transfer::charged))
2045+ {
2046+ qDebug() << Q_FUNC_INFO << "Found destination:" << peer_id << "Direction:" << t->Direction();
2047+ if (t->Direction() == cuc::Transfer::Export)
2048+ {
2049+ qDebug() << Q_FUNC_INFO << "Found import, calling HandleImport";
2050+ if (r->handler->isValid())
2051+ r->handler->HandleImport(QDBusObjectPath{t->import_path()});
2052+ } else if (t->Direction() == cuc::Transfer::Share)
2053+ {
2054+ qDebug() << Q_FUNC_INFO << "Found share, calling HandleShare";
2055+ if (r->handler->isValid())
2056+ r->handler->HandleShare(QDBusObjectPath{t->import_path()});
2057+ }
2058+ }
2059+ }
2060 }
2061
2062=== modified file 'src/com/ubuntu/content/detail/service.h'
2063--- src/com/ubuntu/content/detail/service.h 2013-09-13 16:02:49 +0000
2064+++ src/com/ubuntu/content/detail/service.h 2014-03-19 13:45:37 +0000
2065@@ -53,22 +53,29 @@
2066 Service& operator=(const Service&) = delete;
2067
2068 public Q_SLOTS:
2069- QString DefaultPeerForType(const QString &type_id);
2070- QStringList KnownPeersForType(const QString &type_id);
2071- QDBusObjectPath CreateImportForTypeFromPeer(const QString&, const QString&, const QString&);
2072- void RegisterImportExportHandler(const QString&, const QString&, const QDBusObjectPath& handler);
2073+ QDBusVariant DefaultSourceForType(const QString &type_id);
2074+ QVariantList KnownSourcesForType(const QString &type_id);
2075+ QVariantList KnownDestinationsForType(const QString &type_id);
2076+ QVariantList KnownSharesForType(const QString &type_id);
2077+ QDBusObjectPath CreateImportFromPeer(const QString&, const QString&);
2078+ QDBusObjectPath CreateExportToPeer(const QString&, const QString&);
2079+ QDBusObjectPath CreateShareToPeer(const QString&, const QString&);
2080+
2081+ void RegisterImportExportHandler(const QString&, const QDBusObjectPath& handler);
2082 void Quit();
2083
2084 private:
2085+ bool should_cancel(int);
2086 struct Private;
2087+ struct RegHandler;
2088 QDBusServiceWatcher* m_watcher;
2089 QScopedPointer<Private> d;
2090- void connect_export_handler(const QString&, const QString&);
2091- void connect_import_handler(const QString&, const QString&);
2092
2093 private Q_SLOTS:
2094- void handle_transfer(int);
2095- void handler_registered(const QString&);
2096+ void handle_imports(int);
2097+ void handle_exports(int);
2098+ void handler_unregistered(const QString&);
2099+ QDBusObjectPath CreateTransfer(const QString&, const QString&, int);
2100
2101 };
2102 }
2103
2104=== modified file 'src/com/ubuntu/content/detail/transfer.cpp'
2105--- src/com/ubuntu/content/detail/transfer.cpp 2013-10-10 15:00:36 +0000
2106+++ src/com/ubuntu/content/detail/transfer.cpp 2014-03-19 13:45:37 +0000
2107@@ -32,11 +32,13 @@
2108 {
2109 Private(const int id,
2110 const QString& source,
2111- const QString& destination) :
2112+ const QString& destination,
2113+ const int direction) :
2114 state(cuc::Transfer::created),
2115 id(id),
2116 source(source),
2117 destination(destination),
2118+ direction(direction),
2119 selection_type(cuc::Transfer::single),
2120 source_started_by_content_hub(false)
2121 {
2122@@ -46,6 +48,7 @@
2123 const int id;
2124 const QString source;
2125 const QString destination;
2126+ int direction;
2127 QString store;
2128 int selection_type;
2129 QStringList items;
2130@@ -55,8 +58,9 @@
2131 cucd::Transfer::Transfer(const int id,
2132 const QString& source,
2133 const QString& destination,
2134+ const int direction,
2135 QObject* parent) :
2136- QObject(parent), d(new Private(id, source, destination))
2137+ QObject(parent), d(new Private(id, source, destination, direction))
2138 {
2139 qDebug() << __PRETTY_FUNCTION__;
2140 }
2141@@ -88,6 +92,12 @@
2142 return d->destination;
2143 }
2144
2145+int cucd::Transfer::Direction()
2146+{
2147+ qDebug() << __PRETTY_FUNCTION__;
2148+ return d->direction;
2149+}
2150+
2151 int cucd::Transfer::State()
2152 {
2153 qDebug() << __PRETTY_FUNCTION__;
2154
2155=== modified file 'src/com/ubuntu/content/detail/transfer.h'
2156--- src/com/ubuntu/content/detail/transfer.h 2013-10-10 15:00:36 +0000
2157+++ src/com/ubuntu/content/detail/transfer.h 2014-03-19 13:45:37 +0000
2158@@ -38,9 +38,10 @@
2159 Q_PROPERTY(int id READ Id)
2160 Q_PROPERTY(QString source READ source)
2161 Q_PROPERTY(QString destination READ destination)
2162+ Q_PROPERTY(int direction READ Direction)
2163
2164 public:
2165- Transfer(const int, const QString&, const QString&, QObject* parent = nullptr);
2166+ Transfer(const int, const QString&, const QString&, const int, QObject* parent = nullptr);
2167 Transfer(const Transfer&) = delete;
2168 virtual ~Transfer();
2169
2170@@ -67,6 +68,7 @@
2171 int SelectionType();
2172 void SetSelectionType(int);
2173 int Id();
2174+ int Direction();
2175 QString source();
2176 QString destination();
2177 QString export_path();
2178
2179=== modified file 'src/com/ubuntu/content/hub.cpp'
2180--- src/com/ubuntu/content/hub.cpp 2013-10-01 16:55:39 +0000
2181+++ src/com/ubuntu/content/hub.cpp 2014-03-19 13:45:37 +0000
2182@@ -74,27 +74,19 @@
2183 return;
2184 }
2185
2186- QString bus_name = handler_address(id);
2187- qDebug() << Q_FUNC_INFO << "BUS_NAME:" << bus_name;
2188-
2189 auto c = QDBusConnection::sessionBus();
2190 auto h = new cuc::detail::Handler(c, id, handler);
2191
2192 new HandlerAdaptor(h);
2193- if (not c.registerService(bus_name))
2194- {
2195- qWarning() << Q_FUNC_INFO << "Failed to register name:" << bus_name;
2196- return;
2197- }
2198+
2199
2200 if (not c.registerObject(handler_path(id), h))
2201 {
2202- qWarning() << Q_FUNC_INFO << "Failed to register object for:" << bus_name;
2203+ qWarning() << Q_FUNC_INFO << "Failed to register object for:" << id;
2204 return;
2205 }
2206
2207 d->service->RegisterImportExportHandler(
2208- QString(""),
2209 id,
2210 QDBusObjectPath{handler_path(id)});
2211 }
2212@@ -122,43 +114,82 @@
2213 return it->second;
2214 }
2215
2216-cuc::Peer cuc::Hub::default_peer_for_type(cuc::Type t)
2217+cuc::Peer cuc::Hub::default_source_for_type(cuc::Type t)
2218 {
2219- auto reply = d->service->DefaultPeerForType(t.id());
2220+ qDebug() << Q_FUNC_INFO;
2221+ auto reply = d->service->DefaultSourceForType(t.id());
2222 reply.waitForFinished();
2223
2224 if (reply.isError())
2225 return cuc::Peer::unknown();
2226
2227- return cuc::Peer(reply.value(), this);
2228+ auto peer = reply.value();
2229+ return qdbus_cast<cuc::Peer>(peer.variant());
2230 }
2231
2232-QVector<cuc::Peer> cuc::Hub::known_peers_for_type(cuc::Type t)
2233+QVector<cuc::Peer> cuc::Hub::known_sources_for_type(cuc::Type t)
2234 {
2235 QVector<cuc::Peer> result;
2236
2237- auto reply = d->service->KnownPeersForType(t.id());
2238+ auto reply = d->service->KnownSourcesForType(t.id());
2239 reply.waitForFinished();
2240
2241 if (reply.isError())
2242 return result;
2243
2244- auto ids = reply.value();
2245-
2246- Q_FOREACH(const QString& id, ids)
2247- {
2248- result << cuc::Peer(id, this);
2249- }
2250-
2251- return result;
2252-}
2253-
2254-cuc::Transfer* cuc::Hub::create_import_for_type_from_peer(cuc::Type type, cuc::Peer peer)
2255+ auto peers = reply.value();
2256+
2257+ Q_FOREACH(const QVariant& p, peers)
2258+ {
2259+ result << qdbus_cast<cuc::Peer>(p);
2260+ }
2261+ return result;
2262+}
2263+
2264+QVector<cuc::Peer> cuc::Hub::known_destinations_for_type(cuc::Type t)
2265+{
2266+ QVector<cuc::Peer> result;
2267+
2268+ auto reply = d->service->KnownDestinationsForType(t.id());
2269+ reply.waitForFinished();
2270+
2271+ if (reply.isError())
2272+ return result;
2273+
2274+ auto peers = reply.value();
2275+
2276+ Q_FOREACH(const QVariant& p, peers)
2277+ {
2278+ result << qdbus_cast<cuc::Peer>(p);
2279+ }
2280+ return result;
2281+}
2282+
2283+QVector<cuc::Peer> cuc::Hub::known_shares_for_type(cuc::Type t)
2284+{
2285+ QVector<cuc::Peer> result;
2286+
2287+ auto reply = d->service->KnownSharesForType(t.id());
2288+ reply.waitForFinished();
2289+
2290+ if (reply.isError())
2291+ return result;
2292+
2293+ auto peers = reply.value();
2294+
2295+ Q_FOREACH(const QVariant& p, peers)
2296+ {
2297+ result << qdbus_cast<cuc::Peer>(p);
2298+ }
2299+ return result;
2300+}
2301+
2302+cuc::Transfer* cuc::Hub::create_import_from_peer(cuc::Peer peer)
2303 {
2304 /* This needs to be replaced with a better way to get the APP_ID */
2305 QString id = app_id();
2306
2307- auto reply = d->service->CreateImportForTypeFromPeer(type.id(), peer.id(), id);
2308+ auto reply = d->service->CreateImportFromPeer(peer.id(), id);
2309 reply.waitForFinished();
2310
2311 if (reply.isError())
2312@@ -170,6 +201,49 @@
2313 return transfer;
2314 }
2315
2316+cuc::Transfer* cuc::Hub::create_export_to_peer(cuc::Peer peer)
2317+{
2318+ /* This needs to be replaced with a better way to get the APP_ID */
2319+ QString id = app_id();
2320+
2321+ auto reply = d->service->CreateExportToPeer(peer.id(), id);
2322+ reply.waitForFinished();
2323+
2324+ if (reply.isError())
2325+ return nullptr;
2326+
2327+ cuc::Transfer *transfer = cuc::Transfer::Private::make_transfer(reply.value(), this);
2328+
2329+ QString peerName = peer.id().split("_")[0];
2330+ qDebug() << Q_FUNC_INFO << "peerName: " << peerName;
2331+ const cuc::Store *store = new cuc::Store{QStandardPaths::writableLocation(QStandardPaths::GenericCacheLocation) + "/" + peerName + "/HubIncoming/" + QString::number(transfer->id()), this};
2332+ qDebug() << Q_FUNC_INFO << "STORE:" << store->uri();
2333+ transfer->setStore(store);
2334+ transfer->start();
2335+ return transfer;
2336+}
2337+
2338+cuc::Transfer* cuc::Hub::create_share_to_peer(cuc::Peer peer)
2339+{
2340+ /* This needs to be replaced with a better way to get the APP_ID */
2341+ QString id = app_id();
2342+
2343+ auto reply = d->service->CreateShareToPeer(peer.id(), id);
2344+ reply.waitForFinished();
2345+
2346+ if (reply.isError())
2347+ return nullptr;
2348+
2349+ cuc::Transfer *transfer = cuc::Transfer::Private::make_transfer(reply.value(), this);
2350+ QString peerName = peer.id().split("_")[0];
2351+ qDebug() << Q_FUNC_INFO << "peerName: " << peerName;
2352+ const cuc::Store *store = new cuc::Store{QStandardPaths::writableLocation(QStandardPaths::GenericCacheLocation) + "/" + peerName + "/HubIncoming/" + QString::number(transfer->id()), this};
2353+ qDebug() << Q_FUNC_INFO << "STORE:" << store->uri();
2354+ transfer->setStore(store);
2355+ transfer->start();
2356+ return transfer;
2357+}
2358+
2359 void cuc::Hub::quit()
2360 {
2361 d->service->Quit();
2362
2363=== modified file 'src/com/ubuntu/content/peer.cpp'
2364--- src/com/ubuntu/content/peer.cpp 2013-10-01 16:55:39 +0000
2365+++ src/com/ubuntu/content/peer.cpp 2014-03-19 13:45:37 +0000
2366@@ -16,14 +16,44 @@
2367 * Authored by: Thomas Voß <thomas.voss@canonical.com>
2368 */
2369
2370+
2371 #include <gio/gdesktopappinfo.h>
2372 #include <com/ubuntu/content/peer.h>
2373+#include <QMetaType>
2374
2375 namespace cuc = com::ubuntu::content;
2376
2377 struct cuc::Peer::Private
2378 {
2379+ Private (QString id) : id(id)
2380+ {
2381+ qDebug() << Q_FUNC_INFO << id;
2382+ if (name.isEmpty())
2383+ {
2384+ QString desktop_id(id + ".desktop");
2385+ GDesktopAppInfo* app = g_desktop_app_info_new(desktop_id.toLocal8Bit().data());
2386+ if (G_IS_APP_INFO(app))
2387+ {
2388+ name = QString::fromLatin1(g_app_info_get_display_name(G_APP_INFO(app)));
2389+ GIcon* ic = g_app_info_get_icon(G_APP_INFO(app));
2390+ if (G_IS_ICON(ic))
2391+ {
2392+ iconName = QString::fromUtf8(g_icon_to_string(ic));
2393+
2394+ if (QFile::exists(iconName))
2395+ icon = QImage(iconName);
2396+ g_object_unref(ic);
2397+ }
2398+
2399+ g_object_unref(app);
2400+ }
2401+ }
2402+ }
2403+
2404 QString id;
2405+ QString name;
2406+ QImage icon;
2407+ QString iconName;
2408 };
2409
2410 const cuc::Peer& cuc::Peer::unknown()
2411@@ -34,6 +64,7 @@
2412
2413 cuc::Peer::Peer(const QString& id, QObject* parent) : QObject(parent), d(new cuc::Peer::Private{id})
2414 {
2415+ qDebug() << Q_FUNC_INFO;
2416 }
2417
2418 cuc::Peer::Peer(const cuc::Peer& rhs) : QObject(rhs.parent()), d(rhs.d)
2419@@ -63,11 +94,75 @@
2420 return d->id;
2421 }
2422
2423-QString cuc::Peer::name()
2424-{
2425- QString desktop_id(d->id + ".desktop");
2426- GDesktopAppInfo* app = g_desktop_app_info_new(desktop_id.toLocal8Bit().data());
2427- QString display_name = QString::fromLatin1(g_app_info_get_display_name(G_APP_INFO(app)));
2428- g_object_unref(app);
2429- return display_name;
2430+QString cuc::Peer::name() const
2431+{
2432+ return d->name;
2433+}
2434+
2435+void cuc::Peer::setName(const QString& name)
2436+{
2437+ if (name != d->name)
2438+ d->name = name;
2439+}
2440+
2441+QImage cuc::Peer::icon() const
2442+{
2443+ return d->icon;
2444+}
2445+
2446+void cuc::Peer::setIcon(const QImage& icon)
2447+{
2448+ if (icon != d->icon)
2449+ d->icon = icon;
2450+}
2451+
2452+QString cuc::Peer::iconName() const
2453+{
2454+ return d->iconName;
2455+}
2456+
2457+void cuc::Peer::setIconName(const QString& iconName)
2458+{
2459+ if (iconName != d->iconName)
2460+ d->iconName = iconName;
2461+}
2462+
2463+QDBusArgument &operator<<(QDBusArgument &argument, const cuc::Peer& peer)
2464+{
2465+ QImage i = peer.icon();
2466+ QByteArray ba;
2467+ QBuffer buffer(&ba);
2468+ buffer.open(QIODevice::WriteOnly);
2469+ i.save(&buffer,"PNG");
2470+
2471+ argument.beginStructure();
2472+ argument << peer.id() << peer.name() << ba << peer.iconName();
2473+ argument.endStructure();
2474+ return argument;
2475+}
2476+
2477+const QDBusArgument &operator>>(const QDBusArgument &argument, cuc::Peer &peer)
2478+{
2479+ qDebug() << Q_FUNC_INFO;
2480+ QString id;
2481+ QString name;
2482+ QByteArray ic;
2483+ QString iconName;
2484+
2485+ argument.beginStructure();
2486+ argument >> id >> name >> ic >> iconName;
2487+ argument.endStructure();
2488+
2489+ QImage icon;
2490+ bool ret = icon.loadFromData(reinterpret_cast<const uchar*>(ic.constData()), ic.size(), "png");
2491+ if (ret)
2492+ qDebug() << Q_FUNC_INFO << "SUCCESS";
2493+ else
2494+ qDebug() << Q_FUNC_INFO << "FAIL";
2495+
2496+ peer = cuc::Peer{id};
2497+ peer.setName(name);
2498+ peer.setIcon(icon);
2499+ peer.setIconName(iconName);
2500+ return argument;
2501 }
2502
2503=== modified file 'src/com/ubuntu/content/service/CMakeLists.txt'
2504--- src/com/ubuntu/content/service/CMakeLists.txt 2014-01-29 19:39:49 +0000
2505+++ src/com/ubuntu/content/service/CMakeLists.txt 2014-03-19 13:45:37 +0000
2506@@ -35,7 +35,7 @@
2507 ${CONTENT_SERVICE_SKELETON}
2508 )
2509
2510-qt5_use_modules(content-hub-service Core DBus)
2511+qt5_use_modules(content-hub-service Core DBus Gui)
2512
2513 target_link_libraries(
2514 content-hub-service
2515@@ -69,7 +69,7 @@
2516 hook.cpp
2517 )
2518
2519-qt5_use_modules(content-hub-peer-hook Core)
2520+qt5_use_modules(content-hub-peer-hook Core Gui DBus)
2521
2522 target_link_libraries(
2523 content-hub-peer-hook
2524@@ -94,7 +94,6 @@
2525 "${CMAKE_CURRENT_BINARY_DIR}/content-hub.hook"
2526 )
2527
2528-set(pkglibexecdir "${CMAKE_INSTALL_FULL_LIBEXECDIR}")
2529 configure_file("content-hub.hook.in"
2530 "${CLICK_HOOK}"
2531 @ONLY
2532
2533=== modified file 'src/com/ubuntu/content/service/com.ubuntu.content.hub.gschema.xml'
2534--- src/com/ubuntu/content/service/com.ubuntu.content.hub.gschema.xml 2014-01-29 19:24:02 +0000
2535+++ src/com/ubuntu/content/service/com.ubuntu.content.hub.gschema.xml 2014-03-19 13:45:37 +0000
2536@@ -14,7 +14,35 @@
2537 <default>[]</default>
2538 </key>
2539 </schema>
2540- <schema id="com.ubuntu.content.hub.all" path="/com/ubuntu/content/hub/peers/">
2541+ <schema id="com.ubuntu.content.hub.source" path="/com/ubuntu/content/hub/source/">
2542+ <key name="pictures" type="as">
2543+ <default>[]</default>
2544+ </key>
2545+ <key name="music" type="as">
2546+ <default>[]</default>
2547+ </key>
2548+ <key name="documents" type="as">
2549+ <default>[]</default>
2550+ </key>
2551+ <key name="contacts" type="as">
2552+ <default>[]</default>
2553+ </key>
2554+ </schema>
2555+ <schema id="com.ubuntu.content.hub.destination" path="/com/ubuntu/content/hub/destination/">
2556+ <key name="pictures" type="as">
2557+ <default>[]</default>
2558+ </key>
2559+ <key name="music" type="as">
2560+ <default>[]</default>
2561+ </key>
2562+ <key name="documents" type="as">
2563+ <default>[]</default>
2564+ </key>
2565+ <key name="contacts" type="as">
2566+ <default>[]</default>
2567+ </key>
2568+ </schema>
2569+ <schema id="com.ubuntu.content.hub.share" path="/com/ubuntu/content/hub/share/">
2570 <key name="pictures" type="as">
2571 <default>[]</default>
2572 </key>
2573
2574=== modified file 'src/com/ubuntu/content/service/helper.cpp'
2575--- src/com/ubuntu/content/service/helper.cpp 2013-09-23 20:30:18 +0000
2576+++ src/com/ubuntu/content/service/helper.cpp 2014-03-19 13:45:37 +0000
2577@@ -34,7 +34,7 @@
2578 return 1;
2579 }
2580
2581- new Hook();
2582+ new cuc::detail::Hook();
2583
2584 app.exec();
2585
2586
2587=== modified file 'src/com/ubuntu/content/service/hook.cpp'
2588--- src/com/ubuntu/content/service/hook.cpp 2013-12-10 15:59:15 +0000
2589+++ src/com/ubuntu/content/service/hook.cpp 2014-03-19 13:45:37 +0000
2590@@ -28,21 +28,22 @@
2591
2592 #include "hook.h"
2593
2594-Hook::Hook(QObject *parent) :
2595+namespace cucd = com::ubuntu::content::detail;
2596+
2597+cucd::Hook::Hook(QObject *parent) :
2598 QObject(parent),
2599 registry(new Registry())
2600 {
2601 QTimer::singleShot(200, this, SLOT(run()));
2602 }
2603
2604-
2605-Hook::Hook(com::ubuntu::content::detail::PeerRegistry *registry, QObject *parent) :
2606+cucd::Hook::Hook(com::ubuntu::content::detail::PeerRegistry *registry, QObject *parent) :
2607 QObject(parent),
2608 registry(registry)
2609 {
2610 }
2611
2612-void Hook::run()
2613+void cucd::Hook::run()
2614 {
2615 qDebug() << Q_FUNC_INFO;
2616 /* Looks for files in ${HOME}/.local/share/content-hub/${id} installed
2617@@ -87,10 +88,12 @@
2618 QCoreApplication::instance()->quit();
2619 }
2620
2621-bool Hook::add_peer(QFileInfo result)
2622+bool cucd::Hook::add_peer(QFileInfo result)
2623 {
2624 qDebug() << Q_FUNC_INFO << "Hook:" << result.filePath();
2625
2626+ QStringList knownTypes;
2627+ knownTypes << "pictures" << "music" << "contacts" << "documents";
2628 QString app_id = result.fileName();
2629 auto peer = cuc::Peer(app_id);
2630
2631@@ -109,35 +112,44 @@
2632
2633 QJsonObject contentObj = contentDoc.object();
2634 QVariant sources = contentObj.toVariantMap()["source"];
2635- Q_FOREACH(QString source, sources.toStringList())
2636- {
2637- /* FIXME: we should iterate known types, but there isn't
2638- * really a good way to do that right now */
2639- if (source == "pictures")
2640- {
2641- if (not registry->install_peer_for_type(cuc::Type::Known::pictures(), peer))
2642- qWarning() << "Failed to install peer for" << source;
2643- }
2644- else if (source == "music")
2645- {
2646- if (not registry->install_peer_for_type(cuc::Type::Known::music(), peer))
2647- qWarning() << "Failed to install peer for" << source;
2648- }
2649- else if (source == "documents")
2650- {
2651- if (not registry->install_peer_for_type(cuc::Type::Known::documents(), peer))
2652- qWarning() << "Failed to install peer for" << source;
2653- }
2654- else if (source == "contacts")
2655- {
2656- if (not registry->install_peer_for_type(cuc::Type::Known::contacts(), peer))
2657- qWarning() << "Failed to install peer for" << source;
2658- }
2659+ Q_FOREACH(QString k, sources.toStringList())
2660+ {
2661+ if (knownTypes.contains(k))
2662+ {
2663+ if (registry->install_source_for_type(cuc::Type{k}, peer))
2664+ qDebug() << "Installed source:" << peer.id() << "for type:" << k;
2665+ }
2666+ else
2667+ qWarning() << "Failed to install" << peer.id() << "unknown type:" << k;
2668+ }
2669+
2670+ QVariant dests = contentObj.toVariantMap()["destination"];
2671+ Q_FOREACH(QString k, dests.toStringList())
2672+ {
2673+ if (knownTypes.contains(k))
2674+ {
2675+ if (registry->install_destination_for_type(cuc::Type{k}, peer))
2676+ qDebug() << "Installed destination:" << peer.id() << "for type:" << k;
2677+ }
2678+ else
2679+ qWarning() << "Failed to install" << peer.id() << "unknown type:" << k;
2680+ }
2681+
2682+ QVariant shares = contentObj.toVariantMap()["share"];
2683+ Q_FOREACH(QString k, shares.toStringList())
2684+ {
2685+ if (knownTypes.contains(k))
2686+ {
2687+ if (registry->install_share_for_type(cuc::Type{k}, peer))
2688+ qDebug() << "Installed share:" << peer.id() << "for type:" << k;
2689+ }
2690+ else
2691+ qWarning() << "Failed to install" << peer.id() << "unknown type:" << k;
2692 }
2693 return true;
2694 }
2695
2696-bool Hook::return_error(QString err)
2697+bool cucd::Hook::return_error(QString err)
2698 {
2699 qWarning() << "Failed to install peer" << err;
2700 return false;
2701
2702=== modified file 'src/com/ubuntu/content/service/hook.h'
2703--- src/com/ubuntu/content/service/hook.h 2013-09-25 03:14:53 +0000
2704+++ src/com/ubuntu/content/service/hook.h 2014-03-19 13:45:37 +0000
2705@@ -25,6 +25,14 @@
2706
2707 #include "registry.h"
2708
2709+namespace com
2710+{
2711+namespace ubuntu
2712+{
2713+namespace content
2714+{
2715+namespace detail
2716+{
2717 class Hook : public QObject
2718 {
2719 Q_OBJECT
2720@@ -41,5 +49,9 @@
2721 com::ubuntu::content::detail::PeerRegistry* registry;
2722
2723 };
2724+}
2725+}
2726+}
2727+}
2728
2729 #endif // HOOK_H
2730
2731=== modified file 'src/com/ubuntu/content/service/main.cpp'
2732--- src/com/ubuntu/content/service/main.cpp 2013-10-01 16:55:39 +0000
2733+++ src/com/ubuntu/content/service/main.cpp 2014-03-19 13:45:37 +0000
2734@@ -36,7 +36,7 @@
2735 {
2736 /* list known peers for pictures */
2737 QStringList result;
2738- registry->enumerate_known_peers_for_type(
2739+ registry->enumerate_known_sources_for_type(
2740 cuc::Type::Known::pictures(),
2741 [&result](const cuc::Peer& peer)
2742 {
2743
2744=== modified file 'src/com/ubuntu/content/service/registry.cpp'
2745--- src/com/ubuntu/content/service/registry.cpp 2014-01-29 19:24:02 +0000
2746+++ src/com/ubuntu/content/service/registry.cpp 2014-03-19 13:45:37 +0000
2747@@ -17,80 +17,172 @@
2748 */
2749
2750 #include "registry.h"
2751+#include "utils.cpp"
2752 #include <upstart-app-launch.h>
2753
2754 Registry::Registry() :
2755- m_defaultPeers(new QGSettings("com.ubuntu.content.hub.default",
2756+ m_defaultSources(new QGSettings("com.ubuntu.content.hub.default",
2757 "/com/ubuntu/content/hub/peers/")),
2758- m_peers(new QGSettings("com.ubuntu.content.hub.all",
2759- "/com/ubuntu/content/hub/peers/"))
2760+ m_sources(new QGSettings("com.ubuntu.content.hub.source",
2761+ "/com/ubuntu/content/hub/source/")),
2762+ m_dests(new QGSettings("com.ubuntu.content.hub.destination",
2763+ "/com/ubuntu/content/hub/destination/")),
2764+ m_shares(new QGSettings("com.ubuntu.content.hub.share",
2765+ "/com/ubuntu/content/hub/share/"))
2766 {
2767+ /* ensure all default sources are registered as available sources */
2768+ QList<cuc::Type> types = known_types();
2769+ Q_FOREACH (cuc::Type type, types)
2770+ {
2771+ if (m_defaultSources->keys().contains(type.id()))
2772+ {
2773+ QString peer_id = m_defaultSources->get(type.id()).toString();
2774+ QStringList as(m_defaultSources->get(type.id()).toStringList());
2775+ if (!as.isEmpty())
2776+ {
2777+ std::string pkg = as[0].toStdString();
2778+ std::string app = as[1].toStdString();
2779+ std::string ver = as[2].toStdString();
2780+ cuc::Peer peer(QString::fromLocal8Bit(upstart_app_launch_triplet_to_app_id(pkg.c_str(), app.c_str(), ver.c_str())));
2781+ install_source_for_type(type, cuc::Peer{peer.id()});
2782+ }
2783+ }
2784+ }
2785 }
2786
2787 Registry::~Registry() {}
2788
2789-cuc::Peer Registry::default_peer_for_type(cuc::Type type)
2790-{
2791- qDebug() << Q_FUNC_INFO << type.id();
2792- if (m_defaultPeers->keys().contains(type.id()))
2793- {
2794- QStringList as(m_defaultPeers->get(type.id()).toStringList());
2795- std::string pkg = as[0].toStdString();
2796- std::string app = as[1].toStdString();
2797- std::string ver = as[2].toStdString();
2798- return cuc::Peer(QString::fromLocal8Bit(upstart_app_launch_triplet_to_app_id(pkg.c_str(), app.c_str(), ver.c_str())));
2799- }
2800- else
2801- return cuc::Peer();
2802-}
2803-
2804-void Registry::enumerate_known_peers_for_type(cuc::Type type, const std::function<void(const cuc::Peer&)>&for_each)
2805-{
2806- qDebug() << Q_FUNC_INFO << type.id();
2807-
2808- Q_FOREACH (QString k, m_peers->get(type.id()).toStringList())
2809- {
2810- qDebug() << Q_FUNC_INFO << k;
2811- for_each(k);
2812- }
2813+cuc::Peer Registry::default_source_for_type(cuc::Type type)
2814+{
2815+ qDebug() << Q_FUNC_INFO << type.id();
2816+ if (m_defaultSources->keys().contains(type.id()))
2817+ {
2818+ QStringList as(m_defaultSources->get(type.id()).toStringList());
2819+ if (!as.isEmpty())
2820+ {
2821+ std::string pkg = as[0].toStdString();
2822+ std::string app = as[1].toStdString();
2823+ std::string ver = as[2].toStdString();
2824+ return cuc::Peer(QString::fromLocal8Bit(upstart_app_launch_triplet_to_app_id(pkg.c_str(), app.c_str(), ver.c_str())));
2825+ }
2826+ }
2827+
2828+ return cuc::Peer();
2829 }
2830
2831 void Registry::enumerate_known_peers(const std::function<void(const cuc::Peer&)>&for_each)
2832 {
2833 qDebug() << Q_FUNC_INFO;
2834
2835- Q_FOREACH (QString type_id, m_peers->keys())
2836- {
2837- qDebug() << Q_FUNC_INFO << type_id;
2838- Q_FOREACH (QString k, m_peers->get(type_id).toStringList())
2839- {
2840- qDebug() << Q_FUNC_INFO << k;
2841- for_each(k);
2842- }
2843- }
2844-}
2845-
2846-bool Registry::install_default_peer_for_type(cuc::Type type, cuc::Peer peer)
2847+ Q_FOREACH (QString type_id, m_sources->keys())
2848+ {
2849+ qDebug() << Q_FUNC_INFO << type_id;
2850+ Q_FOREACH (QString k, m_sources->get(type_id).toStringList())
2851+ {
2852+ qDebug() << Q_FUNC_INFO << k;
2853+ for_each(cuc::Peer{k});
2854+ }
2855+ }
2856+ Q_FOREACH (QString type_id, m_dests->keys())
2857+ {
2858+ qDebug() << Q_FUNC_INFO << type_id;
2859+ Q_FOREACH (QString k, m_dests->get(type_id).toStringList())
2860+ {
2861+ qDebug() << Q_FUNC_INFO << k;
2862+ for_each(cuc::Peer{k});
2863+ }
2864+ }
2865+ Q_FOREACH (QString type_id, m_shares->keys())
2866+ {
2867+ qDebug() << Q_FUNC_INFO << type_id;
2868+ Q_FOREACH (QString k, m_shares->get(type_id).toStringList())
2869+ {
2870+ qDebug() << Q_FUNC_INFO << k;
2871+ for_each(cuc::Peer{k});
2872+ }
2873+ }
2874+}
2875+
2876+void Registry::enumerate_known_sources_for_type(cuc::Type type, const std::function<void(const cuc::Peer&)>&for_each)
2877+{
2878+ qDebug() << Q_FUNC_INFO << type.id();
2879+
2880+ if (type == cuc::Type::unknown())
2881+ return;
2882+
2883+ Q_FOREACH (QString k, m_sources->get(type.id()).toStringList())
2884+ {
2885+ qDebug() << Q_FUNC_INFO << k;
2886+ for_each(cuc::Peer{k});
2887+ }
2888+}
2889+
2890+void Registry::enumerate_known_destinations_for_type(cuc::Type type, const std::function<void(const cuc::Peer&)>&for_each)
2891+{
2892+ qDebug() << Q_FUNC_INFO << type.id();
2893+ Q_FOREACH (QString k, m_dests->get(type.id()).toStringList())
2894+ {
2895+ qDebug() << Q_FUNC_INFO << k;
2896+ for_each(cuc::Peer{k});
2897+ }
2898+}
2899+
2900+void Registry::enumerate_known_shares_for_type(cuc::Type type, const std::function<void(const cuc::Peer&)>&for_each)
2901+{
2902+ qDebug() << Q_FUNC_INFO << type.id();
2903+
2904+ Q_FOREACH (QString k, m_shares->get(type.id()).toStringList())
2905+ {
2906+ qDebug() << Q_FUNC_INFO << k;
2907+ for_each(cuc::Peer{k});
2908+ }
2909+}
2910+
2911+bool Registry::install_default_source_for_type(cuc::Type type, cuc::Peer peer)
2912 {
2913 qDebug() << Q_FUNC_INFO << "type:" << type.id() << "peer:" << peer.id();
2914- if (m_defaultPeers->keys().contains(type.id()))
2915+ if (m_defaultSources->keys().contains(type.id()))
2916 {
2917 qDebug() << Q_FUNC_INFO << "Default peer for" << type.id() << "already installed.";
2918 return false;
2919 }
2920
2921- this->install_peer_for_type(type, peer);
2922- return m_defaultPeers->trySet(type.id(), QVariant(peer.id()));
2923-}
2924-
2925-bool Registry::install_peer_for_type(cuc::Type type, cuc::Peer peer)
2926-{
2927- qDebug() << Q_FUNC_INFO << "type:" << type.id() << "peer:" << peer.id();
2928- QStringList l = m_peers->get(type.id()).toStringList();
2929- if (not l.contains(peer.id()))
2930- {
2931- l.append(peer.id());
2932- return m_peers->trySet(type.id(), QVariant(l));
2933+ this->install_source_for_type(type, peer);
2934+ return m_defaultSources->trySet(type.id(), QVariant(peer.id()));
2935+}
2936+
2937+bool Registry::install_source_for_type(cuc::Type type, cuc::Peer peer)
2938+{
2939+ qDebug() << Q_FUNC_INFO << "type:" << type.id() << "peer:" << peer.id();
2940+ QStringList l = m_sources->get(type.id()).toStringList();
2941+ if (not l.contains(peer.id()))
2942+ {
2943+ l.append(peer.id());
2944+ return m_sources->trySet(type.id(), QVariant(l));
2945+ }
2946+ return false;
2947+}
2948+
2949+bool Registry::install_destination_for_type(cuc::Type type, cuc::Peer peer)
2950+{
2951+ qDebug() << Q_FUNC_INFO << "type:" << type.id() << "peer:" << peer.id();
2952+ QStringList l = m_dests->get(type.id()).toStringList();
2953+ if (not l.contains(peer.id()))
2954+ {
2955+ l.append(peer.id());
2956+ return m_dests->trySet(type.id(), QVariant(l));
2957+ }
2958+ return false;
2959+}
2960+
2961+bool Registry::install_share_for_type(cuc::Type type, cuc::Peer peer)
2962+{
2963+ qDebug() << Q_FUNC_INFO << "type:" << type.id() << "peer:" << peer.id();
2964+ QStringList l = m_shares->get(type.id()).toStringList();
2965+ if (not l.contains(peer.id()))
2966+ {
2967+ l.append(peer.id());
2968+ return m_shares->trySet(type.id(), QVariant(l));
2969 }
2970 return false;
2971 }
2972@@ -99,13 +191,31 @@
2973 {
2974 qDebug() << Q_FUNC_INFO << "peer:" << peer.id();
2975 bool ret = false;
2976- Q_FOREACH (QString type_id, m_peers->keys())
2977- {
2978- QStringList l = m_peers->get(type_id).toStringList();
2979- if (l.contains(peer.id()))
2980- {
2981- l.removeAll(peer.id());
2982- ret = m_peers->trySet(type_id, QVariant(l));
2983+ Q_FOREACH (QString type_id, m_sources->keys())
2984+ {
2985+ QStringList l = m_sources->get(type_id).toStringList();
2986+ if (l.contains(peer.id()))
2987+ {
2988+ l.removeAll(peer.id());
2989+ ret = m_sources->trySet(type_id, QVariant(l));
2990+ }
2991+ }
2992+ Q_FOREACH (QString type_id, m_dests->keys())
2993+ {
2994+ QStringList l = m_dests->get(type_id).toStringList();
2995+ if (l.contains(peer.id()))
2996+ {
2997+ l.removeAll(peer.id());
2998+ ret = m_dests->trySet(type_id, QVariant(l));
2999+ }
3000+ }
3001+ Q_FOREACH (QString type_id, m_shares->keys())
3002+ {
3003+ QStringList l = m_shares->get(type_id).toStringList();
3004+ if (l.contains(peer.id()))
3005+ {
3006+ l.removeAll(peer.id());
3007+ ret = m_shares->trySet(type_id, QVariant(l));
3008 }
3009 }
3010 return ret;
3011
3012=== modified file 'src/com/ubuntu/content/service/registry.h'
3013--- src/com/ubuntu/content/service/registry.h 2013-09-20 19:54:51 +0000
3014+++ src/com/ubuntu/content/service/registry.h 2014-03-19 13:45:37 +0000
3015@@ -34,16 +34,22 @@
3016 public:
3017 Registry();
3018 ~Registry();
3019- cuc::Peer default_peer_for_type(cuc::Type type);
3020- void enumerate_known_peers_for_type(cuc::Type type, const std::function<void(const cuc::Peer&)>& for_each);
3021+ cuc::Peer default_source_for_type(cuc::Type type);
3022 void enumerate_known_peers(const std::function<void(const cuc::Peer&)>& for_each);
3023- bool install_default_peer_for_type(cuc::Type type, cuc::Peer peer);
3024- bool install_peer_for_type(cuc::Type type, cuc::Peer peer);
3025+ void enumerate_known_sources_for_type(cuc::Type type, const std::function<void(const cuc::Peer&)>& for_each);
3026+ void enumerate_known_destinations_for_type(cuc::Type type, const std::function<void(const cuc::Peer&)>& for_each);
3027+ void enumerate_known_shares_for_type(cuc::Type type, const std::function<void(const cuc::Peer&)>& for_each);
3028+ bool install_default_source_for_type(cuc::Type type, cuc::Peer peer);
3029+ bool install_source_for_type(cuc::Type type, cuc::Peer peer);
3030+ bool install_destination_for_type(cuc::Type type, cuc::Peer peer);
3031+ bool install_share_for_type(cuc::Type type, cuc::Peer peer);
3032 bool remove_peer(cuc::Peer peer);
3033
3034 private:
3035- QScopedPointer<QGSettings> m_defaultPeers;
3036- QScopedPointer<QGSettings> m_peers;
3037+ QScopedPointer<QGSettings> m_defaultSources;
3038+ QScopedPointer<QGSettings> m_sources;
3039+ QScopedPointer<QGSettings> m_dests;
3040+ QScopedPointer<QGSettings> m_shares;
3041 };
3042
3043 #endif // REGISTRY_H
3044
3045=== modified file 'src/com/ubuntu/content/transfer.cpp'
3046--- src/com/ubuntu/content/transfer.cpp 2013-10-01 16:55:39 +0000
3047+++ src/com/ubuntu/content/transfer.cpp 2014-03-19 13:45:37 +0000
3048@@ -101,3 +101,8 @@
3049 {
3050 return d->setSelectionType(type);
3051 }
3052+
3053+cuc::Transfer::Direction cuc::Transfer::direction() const
3054+{
3055+ return d->direction();
3056+}
3057
3058=== modified file 'src/com/ubuntu/content/transfer_p.h'
3059--- src/com/ubuntu/content/transfer_p.h 2013-10-01 16:55:39 +0000
3060+++ src/com/ubuntu/content/transfer_p.h 2014-03-19 13:45:37 +0000
3061@@ -178,6 +178,18 @@
3062 return not reply.isError();
3063 }
3064
3065+ Direction direction()
3066+ {
3067+ auto reply = remote_transfer->Direction();
3068+ reply.waitForFinished();
3069+
3070+ /* if Direction fails, default to import */
3071+ if (reply.isError())
3072+ return Transfer::Direction::Import;
3073+
3074+ return static_cast<Transfer::Direction>(reply.value());
3075+ }
3076+
3077 com::ubuntu::content::dbus::Transfer* remote_transfer;
3078 };
3079 }
3080
3081=== modified file 'src/com/ubuntu/content/utils.cpp'
3082--- src/com/ubuntu/content/utils.cpp 2013-10-01 16:55:39 +0000
3083+++ src/com/ubuntu/content/utils.cpp 2014-03-19 13:45:37 +0000
3084@@ -27,9 +27,22 @@
3085 #include <nih-dbus/dbus_util.h>
3086
3087 #include "common.h"
3088+#include "com/ubuntu/content/type.h"
3089+
3090+namespace cuc = com::ubuntu::content;
3091
3092 namespace {
3093
3094+QList<cuc::Type> known_types()
3095+{
3096+ QList<cuc::Type> types;
3097+ types << cuc::Type::Known::pictures();
3098+ types << cuc::Type::Known::music();
3099+ types << cuc::Type::Known::documents();
3100+ types << cuc::Type::Known::contacts();
3101+ return types;
3102+}
3103+
3104 /* sanitize the dbus names */
3105 QString sanitize_id(const QString& appId)
3106 {
3107
3108=== modified file 'tests/acceptance-tests/CMakeLists.txt'
3109--- tests/acceptance-tests/CMakeLists.txt 2013-10-09 22:39:03 +0000
3110+++ tests/acceptance-tests/CMakeLists.txt 2014-03-19 13:45:37 +0000
3111@@ -17,14 +17,14 @@
3112 qt5_wrap_cpp(MOCS test_harness.h)
3113
3114 add_executable(
3115- app_hub_communication_default_peer
3116- app_hub_communication_default_peer.cpp
3117+ app_hub_communication_default_source
3118+ app_hub_communication_default_source.cpp
3119 ${MOCS}
3120 )
3121
3122 add_executable(
3123- app_hub_communication_known_peers
3124- app_hub_communication_known_peers.cpp
3125+ app_hub_communication_known_sources
3126+ app_hub_communication_known_sources.cpp
3127 ${MOCS}
3128 )
3129
3130@@ -62,25 +62,25 @@
3131 bad.json
3132 )
3133
3134-qt5_use_modules(app_hub_communication_default_peer Core Test)
3135-qt5_use_modules(app_hub_communication_known_peers Core Test)
3136-qt5_use_modules(app_hub_communication_stores Core Test)
3137-qt5_use_modules(app_hub_communication_transfer Core Test)
3138-qt5_use_modules(app_hub_communication_handler Core Test)
3139+qt5_use_modules(app_hub_communication_default_source Core Gui DBus Test)
3140+qt5_use_modules(app_hub_communication_known_sources Core Gui DBus Test)
3141+qt5_use_modules(app_hub_communication_stores Core Gui DBus Test)
3142+qt5_use_modules(app_hub_communication_transfer Core Gui DBus Test)
3143+qt5_use_modules(app_hub_communication_handler Core Gui DBus Test)
3144 qt5_use_modules(test_utils Core Test)
3145-qt5_use_modules(test_hook Core Test)
3146+qt5_use_modules(test_hook Core Gui DBus Test)
3147
3148 target_link_libraries(app_hub_communication_stores content-hub gmock gtest gtest_main)
3149-target_link_libraries(app_hub_communication_default_peer content-hub gmock gtest gtest_main)
3150-target_link_libraries(app_hub_communication_known_peers content-hub gmock gtest gtest_main)
3151+target_link_libraries(app_hub_communication_default_source content-hub gmock gtest gtest_main)
3152+target_link_libraries(app_hub_communication_known_sources content-hub gmock gtest gtest_main)
3153 target_link_libraries(app_hub_communication_stores content-hub gmock gtest gtest_main)
3154 target_link_libraries(app_hub_communication_transfer content-hub gmock gtest gtest_main)
3155 target_link_libraries(app_hub_communication_handler content-hub gmock gtest gtest_main)
3156 target_link_libraries(test_utils content-hub gmock gtest gtest_main)
3157 target_link_libraries(test_hook content-hub gmock gtest gtest_main ${GSETTINGS_LDFLAGS})
3158
3159-add_test(app_hub_communication_default_peer app_hub_communication_default_peer)
3160-add_test(app_hub_communication_known_peers app_hub_communication_known_peers)
3161+add_test(app_hub_communication_default_source app_hub_communication_default_source)
3162+add_test(app_hub_communication_known_sources app_hub_communication_known_sources)
3163 add_test(app_hub_communication_stores app_hub_communication_stores)
3164 add_test(app_hub_communication_transfer app_hub_communication_transfer)
3165 add_test(app_hub_communication_handler app_hub_communication_handler)
3166
3167=== renamed file 'tests/acceptance-tests/app_hub_communication_default_peer.cpp' => 'tests/acceptance-tests/app_hub_communication_default_source.cpp'
3168--- tests/acceptance-tests/app_hub_communication_default_peer.cpp 2013-09-25 03:14:53 +0000
3169+++ tests/acceptance-tests/app_hub_communication_default_source.cpp 2014-03-19 13:45:37 +0000
3170@@ -60,16 +60,20 @@
3171 {
3172 using namespace ::testing;
3173
3174- ON_CALL(*this, default_peer_for_type(_)).WillByDefault(Return(cuc::Peer::unknown()));
3175- ON_CALL(*this, install_default_peer_for_type(_,_)).WillByDefault(Return(false));
3176- ON_CALL(*this, install_peer_for_type(_,_)).WillByDefault(Return(false));
3177+ ON_CALL(*this, default_source_for_type(_)).WillByDefault(Return(cuc::Peer::unknown()));
3178+ ON_CALL(*this, install_default_source_for_type(_,_)).WillByDefault(Return(false));
3179+ ON_CALL(*this, install_source_for_type(_,_)).WillByDefault(Return(false));
3180 }
3181
3182- MOCK_METHOD1(default_peer_for_type, cuc::Peer(cuc::Type t));
3183- MOCK_METHOD2(enumerate_known_peers_for_type, void(cuc::Type, const std::function<void(const cuc::Peer&)>&));
3184+ MOCK_METHOD1(default_source_for_type, cuc::Peer(cuc::Type t));
3185 MOCK_METHOD1(enumerate_known_peers, void(const std::function<void(const cuc::Peer&)>&));
3186- MOCK_METHOD2(install_default_peer_for_type, bool(cuc::Type, cuc::Peer));
3187- MOCK_METHOD2(install_peer_for_type, bool(cuc::Type, cuc::Peer));
3188+ MOCK_METHOD2(enumerate_known_sources_for_type, void(cuc::Type, const std::function<void(const cuc::Peer&)>&));
3189+ MOCK_METHOD2(enumerate_known_destinations_for_type, void(cuc::Type, const std::function<void(const cuc::Peer&)>&));
3190+ MOCK_METHOD2(enumerate_known_shares_for_type, void(cuc::Type, const std::function<void(const cuc::Peer&)>&));
3191+ MOCK_METHOD2(install_default_source_for_type, bool(cuc::Type, cuc::Peer));
3192+ MOCK_METHOD2(install_source_for_type, bool(cuc::Type, cuc::Peer));
3193+ MOCK_METHOD2(install_destination_for_type, bool(cuc::Type, cuc::Peer));
3194+ MOCK_METHOD2(install_share_for_type, bool(cuc::Type, cuc::Peer));
3195 MOCK_METHOD1(remove_peer, bool(cuc::Peer));
3196 };
3197 }
3198@@ -90,7 +94,7 @@
3199 QDBusConnection connection = QDBusConnection::sessionBus();
3200
3201 auto mock = new MockedPeerRegistry{};
3202- EXPECT_CALL(*mock, default_peer_for_type(_)).
3203+ EXPECT_CALL(*mock, default_source_for_type(_)).
3204 Times(Exactly(1)).
3205 WillRepeatedly(Return(cuc::Peer{default_peer_id}));
3206
3207@@ -124,7 +128,7 @@
3208 test::TestHarness harness;
3209 harness.add_test_case([hub, default_peer_id]()
3210 {
3211- EXPECT_EQ(default_peer_id, hub->default_peer_for_type(cuc::Type::Known::documents()).id());
3212+ EXPECT_EQ(default_peer_id, hub->default_source_for_type(cuc::Type::Known::documents()).id());
3213 });
3214
3215 EXPECT_EQ(0, QTest::qExec(std::addressof(harness)));
3216
3217=== modified file 'tests/acceptance-tests/app_hub_communication_handler.cpp'
3218--- tests/acceptance-tests/app_hub_communication_handler.cpp 2013-09-25 03:14:53 +0000
3219+++ tests/acceptance-tests/app_hub_communication_handler.cpp 2014-03-19 13:45:37 +0000
3220@@ -63,11 +63,15 @@
3221 using namespace ::testing;
3222 }
3223
3224- MOCK_METHOD1(default_peer_for_type, cuc::Peer(cuc::Type t));
3225- MOCK_METHOD2(enumerate_known_peers_for_type, void(cuc::Type, const std::function<void(const cuc::Peer&)>&));
3226+ MOCK_METHOD1(default_source_for_type, cuc::Peer(cuc::Type t));
3227 MOCK_METHOD1(enumerate_known_peers, void(const std::function<void(const cuc::Peer&)>&));
3228- MOCK_METHOD2(install_default_peer_for_type, bool(cuc::Type, cuc::Peer));
3229- MOCK_METHOD2(install_peer_for_type, bool(cuc::Type, cuc::Peer));
3230+ MOCK_METHOD2(enumerate_known_sources_for_type, void(cuc::Type, const std::function<void(const cuc::Peer&)>&));
3231+ MOCK_METHOD2(enumerate_known_destinations_for_type, void(cuc::Type, const std::function<void(const cuc::Peer&)>&));
3232+ MOCK_METHOD2(enumerate_known_shares_for_type, void(cuc::Type, const std::function<void(const cuc::Peer&)>&));
3233+ MOCK_METHOD2(install_default_source_for_type, bool(cuc::Type, cuc::Peer));
3234+ MOCK_METHOD2(install_source_for_type, bool(cuc::Type, cuc::Peer));
3235+ MOCK_METHOD2(install_destination_for_type, bool(cuc::Type, cuc::Peer));
3236+ MOCK_METHOD2(install_share_for_type, bool(cuc::Type, cuc::Peer));
3237 MOCK_METHOD1(remove_peer, bool(cuc::Peer));
3238 };
3239
3240@@ -76,13 +80,14 @@
3241 MockedHandler() : cuc::ImportExportHandler()
3242 {
3243 using namespace ::testing;
3244+ ON_CALL(*this, handle_import(_)).WillByDefault(Return());
3245 ON_CALL(*this, handle_export(_)).WillByDefault(Return());
3246- ON_CALL(*this, handle_import(_)).WillByDefault(Return());
3247-
3248+ ON_CALL(*this, handle_share(_)).WillByDefault(Return());
3249 }
3250
3251+ MOCK_METHOD1(handle_import, void(cuc::Transfer*));
3252 MOCK_METHOD1(handle_export, void(cuc::Transfer*));
3253- MOCK_METHOD1(handle_import, void(cuc::Transfer*));
3254+ MOCK_METHOD1(handle_share, void(cuc::Transfer*));
3255 };
3256 }
3257
3258@@ -139,9 +144,7 @@
3259
3260 qputenv("APP_ID", default_dest_peer_id.toLatin1());
3261 hub = cuc::Hub::Client::instance();
3262- auto transfer = hub->create_import_for_type_from_peer(
3263- cuc::Type::Known::pictures(),
3264- cuc::Peer(default_peer_id));
3265+ auto transfer = hub->create_import_from_peer(cuc::Peer(default_peer_id));
3266 ASSERT_TRUE(transfer != nullptr);
3267 EXPECT_TRUE(transfer->start());
3268 EXPECT_EQ(cuc::Transfer::in_progress, transfer->state());
3269
3270=== renamed file 'tests/acceptance-tests/app_hub_communication_known_peers.cpp' => 'tests/acceptance-tests/app_hub_communication_known_sources.cpp'
3271--- tests/acceptance-tests/app_hub_communication_known_peers.cpp 2013-09-25 03:14:53 +0000
3272+++ tests/acceptance-tests/app_hub_communication_known_sources.cpp 2014-03-19 13:45:37 +0000
3273@@ -59,16 +59,20 @@
3274 {
3275 using namespace ::testing;
3276
3277- ON_CALL(*this, default_peer_for_type(_)).WillByDefault(Return(cuc::Peer::unknown()));
3278- ON_CALL(*this, install_default_peer_for_type(_,_)).WillByDefault(Return(false));
3279- ON_CALL(*this, install_peer_for_type(_,_)).WillByDefault(Return(false));
3280+ ON_CALL(*this, default_source_for_type(_)).WillByDefault(Return(cuc::Peer::unknown()));
3281+ ON_CALL(*this, install_default_source_for_type(_,_)).WillByDefault(Return(false));
3282+ ON_CALL(*this, install_source_for_type(_,_)).WillByDefault(Return(false));
3283 }
3284
3285- MOCK_METHOD1(default_peer_for_type, cuc::Peer(cuc::Type t));
3286- MOCK_METHOD2(enumerate_known_peers_for_type, void(cuc::Type, const std::function<void(const cuc::Peer&)>&));
3287+ MOCK_METHOD1(default_source_for_type, cuc::Peer(cuc::Type t));
3288 MOCK_METHOD1(enumerate_known_peers, void(const std::function<void(const cuc::Peer&)>&));
3289- MOCK_METHOD2(install_default_peer_for_type, bool(cuc::Type, cuc::Peer));
3290- MOCK_METHOD2(install_peer_for_type, bool(cuc::Type, cuc::Peer));
3291+ MOCK_METHOD2(enumerate_known_sources_for_type, void(cuc::Type, const std::function<void(const cuc::Peer&)>&));
3292+ MOCK_METHOD2(enumerate_known_destinations_for_type, void(cuc::Type, const std::function<void(const cuc::Peer&)>&));
3293+ MOCK_METHOD2(enumerate_known_shares_for_type, void(cuc::Type, const std::function<void(const cuc::Peer&)>&));
3294+ MOCK_METHOD2(install_default_source_for_type, bool(cuc::Type, cuc::Peer));
3295+ MOCK_METHOD2(install_source_for_type, bool(cuc::Type, cuc::Peer));
3296+ MOCK_METHOD2(install_destination_for_type, bool(cuc::Type, cuc::Peer));
3297+ MOCK_METHOD2(install_share_for_type, bool(cuc::Type, cuc::Peer));
3298 MOCK_METHOD1(remove_peer, bool(cuc::Peer));
3299 };
3300 }
3301@@ -100,15 +104,15 @@
3302 };
3303
3304 auto mock = new MockedPeerRegistry{};
3305- EXPECT_CALL(*mock, enumerate_known_peers_for_type(_, _)).
3306+ EXPECT_CALL(*mock, enumerate_known_sources_for_type(_, _)).
3307 Times(Exactly(1)).
3308 WillRepeatedly(Invoke(enumerate));
3309
3310- EXPECT_CALL(*mock, install_peer_for_type(_, _)).
3311+ EXPECT_CALL(*mock, install_source_for_type(_, _)).
3312 Times(Exactly(1)).
3313 WillRepeatedly(Return(true));
3314
3315- ASSERT_TRUE(mock->install_peer_for_type(cuc::Type::Known::documents(),
3316+ ASSERT_TRUE(mock->install_source_for_type(cuc::Type::Known::documents(),
3317 cuc::Peer("com.does.not.exist.anywhere.application4")));
3318
3319 QSharedPointer<cucd::PeerRegistry> registry{mock};
3320@@ -141,7 +145,7 @@
3321 test::TestHarness harness;
3322 harness.add_test_case([hub, default_peers]()
3323 {
3324- auto peers = hub->known_peers_for_type(cuc::Type::Known::documents());
3325+ auto peers = hub->known_sources_for_type(cuc::Type::Known::documents());
3326 ASSERT_EQ(default_peers, peers);
3327 });
3328
3329
3330=== modified file 'tests/acceptance-tests/app_hub_communication_stores.cpp'
3331--- tests/acceptance-tests/app_hub_communication_stores.cpp 2013-09-25 03:14:53 +0000
3332+++ tests/acceptance-tests/app_hub_communication_stores.cpp 2014-03-19 13:45:37 +0000
3333@@ -59,16 +59,20 @@
3334 {
3335 using namespace ::testing;
3336
3337- ON_CALL(*this, default_peer_for_type(_)).WillByDefault(Return(cuc::Peer::unknown()));
3338- ON_CALL(*this, install_default_peer_for_type(_,_)).WillByDefault(Return(false));
3339- ON_CALL(*this, install_peer_for_type(_,_)).WillByDefault(Return(false));
3340+ ON_CALL(*this, default_source_for_type(_)).WillByDefault(Return(cuc::Peer::unknown()));
3341+ ON_CALL(*this, install_default_source_for_type(_,_)).WillByDefault(Return(false));
3342+ ON_CALL(*this, install_source_for_type(_,_)).WillByDefault(Return(false));
3343 }
3344
3345- MOCK_METHOD1(default_peer_for_type, cuc::Peer(cuc::Type t));
3346- MOCK_METHOD2(enumerate_known_peers_for_type, void(cuc::Type, const std::function<void(const cuc::Peer&)>&));
3347+ MOCK_METHOD1(default_source_for_type, cuc::Peer(cuc::Type t));
3348 MOCK_METHOD1(enumerate_known_peers, void(const std::function<void(const cuc::Peer&)>&));
3349- MOCK_METHOD2(install_default_peer_for_type, bool(cuc::Type, cuc::Peer));
3350- MOCK_METHOD2(install_peer_for_type, bool(cuc::Type, cuc::Peer));
3351+ MOCK_METHOD2(enumerate_known_sources_for_type, void(cuc::Type, const std::function<void(const cuc::Peer&)>&));
3352+ MOCK_METHOD2(enumerate_known_destinations_for_type, void(cuc::Type, const std::function<void(const cuc::Peer&)>&));
3353+ MOCK_METHOD2(enumerate_known_shares_for_type, void(cuc::Type, const std::function<void(const cuc::Peer&)>&));
3354+ MOCK_METHOD2(install_default_source_for_type, bool(cuc::Type, cuc::Peer));
3355+ MOCK_METHOD2(install_source_for_type, bool(cuc::Type, cuc::Peer));
3356+ MOCK_METHOD2(install_destination_for_type, bool(cuc::Type, cuc::Peer));
3357+ MOCK_METHOD2(install_share_for_type, bool(cuc::Type, cuc::Peer));
3358 MOCK_METHOD1(remove_peer, bool(cuc::Peer));
3359 };
3360 }
3361
3362=== modified file 'tests/acceptance-tests/app_hub_communication_transfer.cpp'
3363--- tests/acceptance-tests/app_hub_communication_transfer.cpp 2013-10-09 22:39:03 +0000
3364+++ tests/acceptance-tests/app_hub_communication_transfer.cpp 2014-03-19 13:45:37 +0000
3365@@ -61,16 +61,20 @@
3366 {
3367 using namespace ::testing;
3368
3369- ON_CALL(*this, default_peer_for_type(_)).WillByDefault(Return(cuc::Peer::unknown()));
3370- ON_CALL(*this, install_default_peer_for_type(_,_)).WillByDefault(Return(false));
3371- ON_CALL(*this, install_peer_for_type(_,_)).WillByDefault(Return(false));
3372+ ON_CALL(*this, default_source_for_type(_)).WillByDefault(Return(cuc::Peer::unknown()));
3373+ ON_CALL(*this, install_default_source_for_type(_,_)).WillByDefault(Return(false));
3374+ ON_CALL(*this, install_source_for_type(_,_)).WillByDefault(Return(false));
3375 }
3376
3377- MOCK_METHOD1(default_peer_for_type, cuc::Peer(cuc::Type t));
3378- MOCK_METHOD2(enumerate_known_peers_for_type, void(cuc::Type, const std::function<void(const cuc::Peer&)>&));
3379+ MOCK_METHOD1(default_source_for_type, cuc::Peer(cuc::Type t));
3380 MOCK_METHOD1(enumerate_known_peers, void(const std::function<void(const cuc::Peer&)>&));
3381- MOCK_METHOD2(install_default_peer_for_type, bool(cuc::Type, cuc::Peer));
3382- MOCK_METHOD2(install_peer_for_type, bool(cuc::Type, cuc::Peer));
3383+ MOCK_METHOD2(enumerate_known_sources_for_type, void(cuc::Type, const std::function<void(const cuc::Peer&)>&));
3384+ MOCK_METHOD2(enumerate_known_destinations_for_type, void(cuc::Type, const std::function<void(const cuc::Peer&)>&));
3385+ MOCK_METHOD2(enumerate_known_shares_for_type, void(cuc::Type, const std::function<void(const cuc::Peer&)>&));
3386+ MOCK_METHOD2(install_default_source_for_type, bool(cuc::Type, cuc::Peer));
3387+ MOCK_METHOD2(install_source_for_type, bool(cuc::Type, cuc::Peer));
3388+ MOCK_METHOD2(install_destination_for_type, bool(cuc::Type, cuc::Peer));
3389+ MOCK_METHOD2(install_share_for_type, bool(cuc::Type, cuc::Peer));
3390 MOCK_METHOD1(remove_peer, bool(cuc::Peer));
3391 };
3392 }
3393@@ -91,8 +95,8 @@
3394 QDBusConnection connection = QDBusConnection::sessionBus();
3395
3396 auto mock = new ::testing::NiceMock<MockedPeerRegistry>{};
3397- EXPECT_CALL(*mock, default_peer_for_type(_)).
3398- Times(Exactly(1)).
3399+ EXPECT_CALL(*mock, default_source_for_type(_)).
3400+ Times(AtLeast(1)).
3401 WillRepeatedly(Return(cuc::Peer{default_peer_id}));
3402
3403 QSharedPointer<cucd::PeerRegistry> registry{mock};
3404@@ -134,9 +138,8 @@
3405
3406 /** [Importing pictures] */
3407 auto hub = cuc::Hub::Client::instance();
3408- auto transfer = hub->create_import_for_type_from_peer(
3409- cuc::Type::Known::pictures(),
3410- hub->default_peer_for_type(cuc::Type::Known::pictures()));
3411+ auto transfer = hub->create_import_from_peer(
3412+ hub->default_source_for_type(cuc::Type::Known::pictures()));
3413 ASSERT_TRUE(transfer != nullptr);
3414 EXPECT_EQ(cuc::Transfer::created, transfer->state());
3415 EXPECT_TRUE(transfer->setSelectionType(cuc::Transfer::SelectionType::multiple));
3416@@ -150,6 +153,25 @@
3417 EXPECT_EQ(cuc::Transfer::charged, transfer->state());
3418 EXPECT_EQ(expected_items, transfer->collect());
3419 /** [Importing pictures] */
3420+
3421+
3422+ /* Test that only a single transfer exists for the same peer */
3423+ auto single_transfer = hub->create_import_from_peer(
3424+ hub->default_source_for_type(cuc::Type::Known::pictures()));
3425+ ASSERT_TRUE(single_transfer != nullptr);
3426+ EXPECT_EQ(cuc::Transfer::created, single_transfer->state());
3427+ EXPECT_TRUE(single_transfer->start());
3428+ EXPECT_EQ(cuc::Transfer::initiated, single_transfer->state());
3429+
3430+ auto second_transfer = hub->create_import_from_peer(
3431+ hub->default_source_for_type(cuc::Type::Known::pictures()));
3432+ ASSERT_TRUE(second_transfer != nullptr);
3433+ EXPECT_EQ(cuc::Transfer::created, second_transfer->state());
3434+ /* Now that a second transfer was created, the previous
3435+ * transfer should have been aborted */
3436+ EXPECT_EQ(cuc::Transfer::aborted, single_transfer->state());
3437+ /* end single transfer test */
3438+
3439 hub->quit();
3440 });
3441 EXPECT_EQ(0, QTest::qExec(std::addressof(harness)));
3442
3443=== modified file 'tests/acceptance-tests/app_manager_mock.h'
3444--- tests/acceptance-tests/app_manager_mock.h 2013-09-06 10:17:01 +0000
3445+++ tests/acceptance-tests/app_manager_mock.h 2014-03-19 13:45:37 +0000
3446@@ -31,7 +31,7 @@
3447
3448 ON_CALL(*this, invoke_application(_)).WillByDefault(Return(true));
3449 ON_CALL(*this, stop_application(_)).WillByDefault(Return(true));
3450- ON_CALL(*this, is_application_started(_)).WillByDefault(Return(false));
3451+ ON_CALL(*this, is_application_started(_)).WillByDefault(Return(true));
3452 }
3453
3454 MOCK_METHOD1(invoke_application, bool(const std::string &));
3455
3456=== modified file 'tests/acceptance-tests/test_hook.cpp'
3457--- tests/acceptance-tests/test_hook.cpp 2013-09-25 03:14:53 +0000
3458+++ tests/acceptance-tests/test_hook.cpp 2014-03-19 13:45:37 +0000
3459@@ -40,18 +40,21 @@
3460 {
3461 using namespace ::testing;
3462
3463- ON_CALL(*this, default_peer_for_type(_)).WillByDefault(Return(cuc::Peer::unknown()));
3464- ON_CALL(*this, install_default_peer_for_type(_,_)).WillByDefault(Return(false));
3465- ON_CALL(*this, install_peer_for_type(_,_)).WillByDefault(Return(false));
3466+ ON_CALL(*this, default_source_for_type(_)).WillByDefault(Return(cuc::Peer::unknown()));
3467+ ON_CALL(*this, install_default_source_for_type(_,_)).WillByDefault(Return(false));
3468+ ON_CALL(*this, install_source_for_type(_,_)).WillByDefault(Return(false));
3469 ON_CALL(*this, remove_peer(_)).WillByDefault(Return(false));
3470 }
3471
3472- MOCK_METHOD1(default_peer_for_type, cuc::Peer(cuc::Type t));
3473- MOCK_METHOD2(enumerate_known_peers_for_type, void(cuc::Type, const std::function<void(const cuc::Peer&)>&));
3474-
3475- MOCK_METHOD2(install_default_peer_for_type, bool(cuc::Type, cuc::Peer));
3476- MOCK_METHOD2(install_peer_for_type, bool(cuc::Type, cuc::Peer));
3477+ MOCK_METHOD1(default_source_for_type, cuc::Peer(cuc::Type t));
3478 MOCK_METHOD1(enumerate_known_peers, void(const std::function<void(const cuc::Peer&)>&));
3479+ MOCK_METHOD2(enumerate_known_sources_for_type, void(cuc::Type, const std::function<void(const cuc::Peer&)>&));
3480+ MOCK_METHOD2(enumerate_known_destinations_for_type, void(cuc::Type, const std::function<void(const cuc::Peer&)>&));
3481+ MOCK_METHOD2(enumerate_known_shares_for_type, void(cuc::Type, const std::function<void(const cuc::Peer&)>&));
3482+ MOCK_METHOD2(install_default_source_for_type, bool(cuc::Type, cuc::Peer));
3483+ MOCK_METHOD2(install_source_for_type, bool(cuc::Type, cuc::Peer));
3484+ MOCK_METHOD2(install_destination_for_type, bool(cuc::Type, cuc::Peer));
3485+ MOCK_METHOD2(install_share_for_type, bool(cuc::Type, cuc::Peer));
3486 MOCK_METHOD1(remove_peer, bool(cuc::Peer));
3487 };
3488 }
3489@@ -61,12 +64,12 @@
3490 using namespace ::testing;
3491
3492 auto mock = new MockedRegistry{};
3493- EXPECT_CALL(*mock, install_peer_for_type(_,_)).
3494+ EXPECT_CALL(*mock, install_source_for_type(_,_)).
3495 Times(Exactly(2)).
3496 WillRepeatedly(Return(true));
3497
3498 QFileInfo f("good.json");
3499- Hook *hook = new Hook(mock);
3500+ cucd::Hook *hook = new cucd::Hook(mock);
3501
3502 EXPECT_TRUE(hook->add_peer(f));
3503 f.setFile("bad.json");

Subscribers

People subscribed via source and target branches