summaryrefslogtreecommitdiffstats
blob: c20d2c7b57053345a1cd93e67fd36f02bf650532 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
/*
 * Copyright (c) 2012 Yoann Blein
 * Licensed under the simplified BSD license.
 * See Documentation/Licenses/BSD-simplified.txt for more information.
 */

#include <Swiften/ScreenSharing/ScreenSharingManagerImpl.h>

#include <Swiften/Base/foreach.h>
#include <Swiften/Disco/EntityCapsProvider.h>
#include <Swiften/Elements/Presence.h>
#include <Swiften/Presence/PresenceOracle.h>
#include <Swiften/ScreenSharing/IncomingScreenSharingManager.h>
#include <Swiften/ScreenSharing/OutgoingScreenSharingManager.h>
#include <Swiften/ScreenSharing/OutgoingScreenSharing.h>
#include <Swiften/ScreenSharing/InputEventResponder.h>

#include <boost/foreach.hpp>

namespace Swift {

ScreenSharingManagerImpl::ScreenSharingManagerImpl(const JID& ownFullJID, JingleSessionManager *jingleSessionManager, IQRouter *iqRouter,
												   UDPSocketFactory* udpSocketFactory, TimerFactory* timerFactory, PresenceOracle* presenceOrable,
												   EntityCapsProvider* capsProvider)
	: ownJID(ownFullJID), capsProvider(capsProvider),  presenceOracle(presenceOrable)
{
	incomingSSManager = new IncomingScreenSharingManager(jingleSessionManager, iqRouter, udpSocketFactory, timerFactory);
	outgoingSSManager = new OutgoingScreenSharingManager(jingleSessionManager, iqRouter, udpSocketFactory, timerFactory);

	responder = new InputEventResponder(this, iqRouter);
	responder->start();

	incomingSSManager->onIncomingScreenSharing.connect(onIncomingScreenSharing);
}

ScreenSharingManagerImpl::~ScreenSharingManagerImpl()
{
	responder->stop();
	delete responder;
	delete incomingSSManager;
	delete outgoingSSManager;
}

boost::shared_ptr<OutgoingScreenSharing> ScreenSharingManagerImpl::createOutgoingScreenSharing(const JID &to)
{
	JID recipient = to;

	if (recipient.isBare()) {
		boost::optional<JID> fullJID = highestPriorityJIDSupportingScreenSharing(recipient);
		if (fullJID.is_initialized()) {
			recipient = fullJID.get();
		} else {
			return boost::shared_ptr<OutgoingScreenSharing>();
		}
	}

	OutgoingScreenSharing::ref oss = outgoingSSManager->createOutgoingScreenSharing(ownJID, recipient);
	outgoingSharings.push_back(oss);
	return oss;
}

void ScreenSharingManagerImpl::handleInputEvent(const JID& from, boost::shared_ptr<InputEventPayload> payload)
{
	foreach (OutgoingScreenSharing::ref oss, outgoingSharings) {
		if (oss->getRecipient() == from) {
			oss->onNewInputEvent(payload);
		}
	}
}

boost::optional<JID> ScreenSharingManagerImpl::highestPriorityJIDSupportingScreenSharing(const JID& bareJID) {
	int priority = INT_MIN;
	JID fullRecipientJID;

	std::vector<Presence::ref> presences = presenceOracle->getAllPresence(bareJID);
	foreach (Presence::ref pres, presences) {
		if (pres->getPriority() > priority) {
			DiscoInfo::ref info = capsProvider->getCaps(pres->getFrom()); // look up caps from the jid
			if (info && info->hasFeature(DiscoInfo::JingleFeature)
					&& info->hasFeature(DiscoInfo::JingleRTPFeature)
					&& info->hasFeature(DiscoInfo::JingleTransportRawUDPFeature)
					&& info->hasFeature(DiscoInfo::JingleScreenSharingFeature)) {
				priority = pres->getPriority();
				fullRecipientJID = pres->getFrom();
			}
		}
	}

	return fullRecipientJID.isValid() ? boost::optional<JID>(fullRecipientJID) : boost::optional<JID>();
}

}