From 877c46628fa2836f9226e24a3d0a84b9a3f821e6 Mon Sep 17 00:00:00 2001 From: hrxi Date: Sun, 23 Jun 2019 14:53:18 +0200 Subject: Implement file sending via Jingle This is still disabled by default until prioritization is implemented; otherwise this could be preferred to HTTP uploads. File sending only works via Jingle In-Band-Bytestreams right now, more transports are going to be implemented. To test this, uncomment the line with `JingleFileTransfer` in libdino/src/application.vala. --- libdino/CMakeLists.txt | 1 + libdino/src/application.vala | 1 + libdino/src/entity/file_transfer.vala | 1 + libdino/src/service/file_manager.vala | 1 + libdino/src/service/jingle_file_manager.vala | 52 ++++++++++++++++++++++++++++ libdino/src/service/module_manager.vala | 4 +++ 6 files changed, 60 insertions(+) create mode 100644 libdino/src/service/jingle_file_manager.vala (limited to 'libdino') diff --git a/libdino/CMakeLists.txt b/libdino/CMakeLists.txt index 6d37ef15..73386d0a 100644 --- a/libdino/CMakeLists.txt +++ b/libdino/CMakeLists.txt @@ -35,6 +35,7 @@ SOURCES src/service/database.vala src/service/entity_capabilities_storage.vala src/service/file_manager.vala + src/service/jingle_file_manager.vala src/service/message_processor.vala src/service/message_storage.vala src/service/module_manager.vala diff --git a/libdino/src/application.vala b/libdino/src/application.vala index da098fb4..b1838607 100644 --- a/libdino/src/application.vala +++ b/libdino/src/application.vala @@ -37,6 +37,7 @@ public interface Dino.Application : GLib.Application { RosterManager.start(stream_interactor, db); ChatInteraction.start(stream_interactor); FileManager.start(stream_interactor, db); + //JingleFileManager.start(stream_interactor); // TODO(hrxi): Activate ContentItemStore.start(stream_interactor, db); NotificationEvents.start(stream_interactor); SearchProcessor.start(stream_interactor, db); diff --git a/libdino/src/entity/file_transfer.vala b/libdino/src/entity/file_transfer.vala index 6b1492d6..68234a48 100644 --- a/libdino/src/entity/file_transfer.vala +++ b/libdino/src/entity/file_transfer.vala @@ -53,6 +53,7 @@ public class FileTransfer : Object { } public string path { get; set; } public string? mime_type { get; set; } + // TODO(hrxi): expand to 64 bit public int size { get; set; } public State state { get; set; } diff --git a/libdino/src/service/file_manager.vala b/libdino/src/service/file_manager.vala index 6f8ccee4..9873539a 100644 --- a/libdino/src/service/file_manager.vala +++ b/libdino/src/service/file_manager.vala @@ -65,6 +65,7 @@ public class FileManager : StreamInteractionModule, Object { foreach (FileSender file_sender in file_senders) { if (file_sender.can_send(conversation, file_transfer)) { + // TODO(hrxi): Currently, this tries to send the file with every transfer available, but it should probably only select one. file_sender.send_file(conversation, file_transfer); } } diff --git a/libdino/src/service/jingle_file_manager.vala b/libdino/src/service/jingle_file_manager.vala new file mode 100644 index 00000000..055f0758 --- /dev/null +++ b/libdino/src/service/jingle_file_manager.vala @@ -0,0 +1,52 @@ +using Gdk; +using Gee; + +using Xmpp; +using Dino.Entities; + +namespace Dino { + +public class JingleFileManager : StreamInteractionModule, FileSender, Object { + public static ModuleIdentity IDENTITY = new ModuleIdentity("jingle_files"); + public string id { get { return IDENTITY.id; } } + + private StreamInteractor stream_interactor; + + public static void start(StreamInteractor stream_interactor) { + JingleFileManager m = new JingleFileManager(stream_interactor); + stream_interactor.add_module(m); + } + + private JingleFileManager(StreamInteractor stream_interactor) { + this.stream_interactor = stream_interactor; + + stream_interactor.get_module(FileManager.IDENTITY).add_sender(this); + } + + public bool is_upload_available(Conversation conversation) { + // TODO(hrxi) Here and in `send_file`: What should happen if `stream == null`? + XmppStream? stream = stream_interactor.get_stream(conversation.account); + foreach (Jid full_jid in stream.get_flag(Presence.Flag.IDENTITY).get_resources(conversation.counterpart)) { + if (stream.get_module(Xep.JingleFileTransfer.Module.IDENTITY).is_available(stream, full_jid)) { + return true; + } + } + return false; + } + public bool can_send(Conversation conversation, FileTransfer file_transfer) { + return file_transfer.encryption != Encryption.OMEMO; + } + public void send_file(Conversation conversation, FileTransfer file_transfer) { + XmppStream? stream = stream_interactor.get_stream(file_transfer.account); + foreach (Jid full_jid in stream.get_flag(Presence.Flag.IDENTITY).get_resources(conversation.counterpart)) { + // TODO(hrxi): Prioritization of transports (and resources?). + if (!stream.get_module(Xep.JingleFileTransfer.Module.IDENTITY).is_available(stream, full_jid)) { + continue; + } + stream.get_module(Xep.JingleFileTransfer.Module.IDENTITY).offer_file_stream(stream, full_jid, file_transfer.input_stream, file_transfer.file_name, file_transfer.size); + return; + } + } +} + +} diff --git a/libdino/src/service/module_manager.vala b/libdino/src/service/module_manager.vala index 41a2c6a0..16bf5a60 100644 --- a/libdino/src/service/module_manager.vala +++ b/libdino/src/service/module_manager.vala @@ -78,6 +78,10 @@ public class ModuleManager { module_map[account].add(new StreamError.Module()); module_map[account].add(new Xep.InBandRegistration.Module()); module_map[account].add(new Xep.HttpFileUpload.Module()); + module_map[account].add(new Xep.InBandBytestreams.Module()); + module_map[account].add(new Xep.Jingle.Module()); + module_map[account].add(new Xep.JingleInBandBytestreams.Module()); + module_map[account].add(new Xep.JingleFileTransfer.Module()); initialize_account_modules(account, module_map[account]); } } -- cgit v1.2.3-54-g00ecf