Skip to content

Commit

Permalink
Fix remote muting jigasi participants (jitsi#258)
Browse files Browse the repository at this point in the history
* fix: NPE when sip participants is leaving the call.

SEVERE: [108354] org.jitsi.jigasi.util.Util.lambda$injectSoundFile$0().295 Error playing:sounds/ParticipantLeft.opus
org.jitsi.service.neomedia.TransmissionFailedException: java.lang.NullPointerException
	at org.jitsi.impl.neomedia.MediaStreamImpl.injectPacket(MediaStreamImpl.java:3775)
	at org.jitsi.jigasi.SoundNotificationManager.injectSoundFileInStream(SoundNotificationManager.java:349)
	at org.jitsi.jigasi.SoundNotificationManager.lambda$injectSoundFile$0(SoundNotificationManager.java:290)
	at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.NullPointerException
	at org.jitsi.impl.neomedia.MediaStreamImpl.injectPacket(MediaStreamImpl.java:3767)
	... 3 more

* fix: Uses private method to get connection.

* fix: Muting jigasi participants and handling start muted.

* fix: Lock when initializing providers.

"org.jitsi.impl.osgi.framework.AsyncExecutor" jitsi#14 daemon prio=5 os_prio=31 tid=0x00007ffe34c30000 nid=0xa703 in Object.wait() [0x000070000913c000]
   java.lang.Thread.State: RUNNABLE
	at org.jivesoftware.smack.SmackConfiguration.getVersion(SmackConfiguration.java:96)
	at org.jivesoftware.smack.provider.ProviderManager.<clinit>(ProviderManager.java:122)
	at org.jitsi.xmpp.extensions.jitsimeet.MediaPresenceExtension.registerExtensions(MediaPresenceExtension.java:59)
	at org.jitsi.jigasi.JigasiBundleActivator.serviceChanged(JigasiBundleActivator.java:284)
	at org.jitsi.impl.osgi.framework.launch.EventDispatcher$Command.run(EventDispatcher.java:128)
	at org.jitsi.impl.osgi.framework.AsyncExecutor.runInThread(AsyncExecutor.java:122)
	at org.jitsi.impl.osgi.framework.AsyncExecutor.access$000(AsyncExecutor.java:28)
	at org.jitsi.impl.osgi.framework.AsyncExecutor$1.run(AsyncExecutor.java:231)

"org.jitsi.impl.osgi.framework.AsyncExecutor" jitsi#13 daemon prio=5 os_prio=31 tid=0x00007ffe339a4800 nid=0xa803 in Object.wait() [0x0000700009038000]
   java.lang.Thread.State: RUNNABLE
	at org.jivesoftware.smack.initializer.UrlInitializer.initialize(UrlInitializer.java:54)
	at org.jivesoftware.smack.SmackInitialization.loadSmackClass(SmackInitialization.java:237)
	at org.jivesoftware.smack.SmackInitialization.parseClassesToLoad(SmackInitialization.java:198)
	at org.jivesoftware.smack.SmackInitialization.processConfigFile(SmackInitialization.java:168)
	at org.jivesoftware.smack.SmackInitialization.processConfigFile(SmackInitialization.java:153)
	at org.jivesoftware.smack.SmackInitialization.<clinit>(SmackInitialization.java:119)
	at org.jivesoftware.smack.SmackConfiguration.getVersion(SmackConfiguration.java:96)
	at org.jivesoftware.smack.AbstractXMPPConnection.<clinit>(AbstractXMPPConnection.java:109)
	at org.jitsi.jigasi.xmpp.CallControlMucActivator.<clinit>(CallControlMucActivator.java:83)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
	at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
	at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
	at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
	at java.lang.Class.newInstance(Class.java:442)
	at org.jitsi.impl.osgi.framework.BundleImpl.start(BundleImpl.java:305)
	at org.jitsi.impl.osgi.framework.launch.FrameworkImpl.startLevelChanged(FrameworkImpl.java:472)
	at org.jitsi.impl.osgi.framework.startlevel.FrameworkStartLevelImpl$Command.run(FrameworkStartLevelImpl.java:137)
	at org.jitsi.impl.osgi.framework.AsyncExecutor.runInThread(AsyncExecutor.java:122)
	at org.jitsi.impl.osgi.framework.AsyncExecutor.access$000(AsyncExecutor.java:28)
	at org.jitsi.impl.osgi.framework.AsyncExecutor$1.run(AsyncExecutor.java:231)

"AccountManager.loadStoredAccounts" jitsi#23 daemon prio=5 os_prio=31 tid=0x00007ffe33a8d800 nid=0x29107 in Object.wait() [0x0000700009d6d000]
   java.lang.Thread.State: RUNNABLE
	at org.jitsi.xmpp.extensions.jingle.JingleIQProvider.<init>(JingleIQProvider.java:44)
	at net.java.sip.communicator.impl.protocol.jabber.ProtocolProviderServiceJabberImpl.initialize(ProtocolProviderServiceJabberImpl.java:1800)
	- locked <0x00000006c002e0d8> (a java.lang.Object)
	at net.java.sip.communicator.impl.protocol.jabber.ProtocolProviderFactoryJabberImpl.createService(ProtocolProviderFactoryJabberImpl.java:173)
	at net.java.sip.communicator.service.protocol.ProtocolProviderFactory.loadAccount(ProtocolProviderFactory.java:1010)
	at net.java.sip.communicator.service.protocol.AccountManager.doLoadStoredAccounts(AccountManager.java:218)
	at net.java.sip.communicator.service.protocol.AccountManager.loadStoredAccounts(AccountManager.java:468)
	at net.java.sip.communicator.service.protocol.AccountManager.runInLoadStoredAccountsThread(AccountManager.java:585)
	at net.java.sip.communicator.service.protocol.AccountManager.access$100(AccountManager.java:37)
	at net.java.sip.communicator.service.protocol.AccountManager$2.run(AccountManager.java:510)

* ref: Simplifies code.

* fix: Sets JitsiMeetTools RequestListener when setting up sip call.

And removes it when call is ended.

* fix: Show correct presence status in meeting when remotely muted.

* fix: Sending SIP Info messages only on established call.
  • Loading branch information
damencho authored Apr 14, 2020
1 parent 3b2a0e5 commit 0798301
Show file tree
Hide file tree
Showing 6 changed files with 204 additions and 87 deletions.
11 changes: 11 additions & 0 deletions src/main/java/org/jitsi/jigasi/AbstractGatewaySession.java
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,12 @@ abstract void onJvbConferenceWillStop(JvbConference jvbConference,
*/
public void onJvbCallEnded() {}

/**
* Method called by <tt>JvbConference</tt> to notify JVB call has been
* established.
*/
public void onJvbCallEstablished() {}

/**
* Cancels current session by leaving the muc room
*/
Expand Down Expand Up @@ -410,6 +416,11 @@ public String getFocusResourceAddr()
return focusResourceAddr;
}

/**
* If muting is supported will mute the participant.
*/
public abstract void mute();

/**
* Whether the gateway implementation supports call resuming. Where we can
* keep the gateway session while the xmpp call is been disconnected or
Expand Down
29 changes: 15 additions & 14 deletions src/main/java/org/jitsi/jigasi/JigasiBundleActivator.java
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,15 @@ public void start(final BundleContext bundleContext)

if(isSipEnabled())
{
MuteIqProvider.registerMuteIqProvider();

// recording status, to detect recording start/stop
ProviderManager.addExtensionProvider(
RecordingStatus.ELEMENT_NAME,
RecordingStatus.NAMESPACE,
new DefaultPacketExtensionProvider<>(RecordingStatus.class)
);

logger.info("initialized SipGateway");
sipGateway = new SipGateway(bundleContext)
{
Expand Down Expand Up @@ -222,9 +231,14 @@ void notifyCallEnded(CallContext callContext)
else
{
logger.info("skipped initialization of TranscriptionGateway");

}

// Register Jitsi Meet media presence extension.
MediaPresenceExtension.registerExtensions();

// Register Rayo IQs
new RayoIqProvider().registerRayoIQs();

bundleContext.addServiceListener(this);

Collection<ServiceReference<ProtocolProviderService>> refs
Expand Down Expand Up @@ -273,19 +287,6 @@ public void serviceChanged(ServiceEvent serviceEvent)
return;
}

// Register Jitsi Meet media presence extension.
MediaPresenceExtension.registerExtensions();

// Register Rayo IQs
new RayoIqProvider().registerRayoIQs();

// recording status, to detect recording start/stop
ProviderManager.addExtensionProvider(
RecordingStatus.ELEMENT_NAME,
RecordingStatus.NAMESPACE,
new DefaultPacketExtensionProvider<>(RecordingStatus.class)
);

ProtocolProviderService pps = (ProtocolProviderService) service;
if (sipGateway != null && sipGateway.getSipProvider() == null &&
ProtocolNames.SIP.equals(pps.getProtocolName()))
Expand Down
77 changes: 69 additions & 8 deletions src/main/java/org/jitsi/jigasi/JvbConference.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
import org.jitsi.xmpp.extensions.rayo.*;
import org.jivesoftware.smack.*;
import org.jivesoftware.smack.bosh.*;
import org.jivesoftware.smack.iqrequest.*;
import org.jivesoftware.smack.packet.*;
import org.jivesoftware.smackx.nick.packet.*;
import org.jxmpp.jid.*;
Expand Down Expand Up @@ -582,14 +583,12 @@ public synchronized void registrationStateChanged(
// Join the MUC
joinConferenceRoom();

XMPPConnection connection = getConnection();
if (xmppProvider != null
&& xmppProvider instanceof ProtocolProviderServiceJabberImpl
&& ((ProtocolProviderServiceJabberImpl) xmppProvider)
.getConnection() instanceof XMPPBOSHConnection)
&& connection != null
&& connection instanceof XMPPBOSHConnection)
{
Object sessionId = Util.getConnSessionId(
((ProtocolProviderServiceJabberImpl) xmppProvider)
.getConnection());
Object sessionId = Util.getConnSessionId(connection);
if (sessionId != null)
{
logger.error(this.callContext + " Registered bosh sid: "
Expand Down Expand Up @@ -643,6 +642,15 @@ public boolean isInTheRoom()
return mucRoom != null && mucRoom.isJoined();
}

/**
* Indicates whether this conference has been started.
* @return <tt>true</tt> is this conference is started, false otherwise.
*/
public boolean isStarted()
{
return started;
}

private void joinConferenceRoom()
{
// Advertise gateway feature before joining
Expand Down Expand Up @@ -747,6 +755,11 @@ private void joinConferenceRoom()
"is not an instance of ChatRoomJabberImpl");
}

if (JigasiBundleActivator.isSipStartMutedEnabled())
{
getConnection().registerIQRequestHandler(new MuteIqHandler());
}

// we invite focus and wait for its response
// to be sure that if it is not in the room, the focus will be the
// first to join, mimic the web behaviour
Expand Down Expand Up @@ -1158,6 +1171,7 @@ public synchronized void callStateChanged(CallChangeEvent evt)
if (jvbCall.getCallState() == CallState.CALL_IN_PROGRESS)
{
logger.info(callContext + " JVB conference call IN_PROGRESS.");
gatewaySession.onJvbCallEstablished();
}
else if(jvbCall.getCallState() == CallState.CALL_ENDED)
{
Expand Down Expand Up @@ -1407,8 +1421,7 @@ private void inviteFocus(final EntityBareJid roomIdentifier)
StanzaCollector collector = null;
try
{
collector = ((ProtocolProviderServiceJabberImpl) xmppProvider)
.getConnection()
collector = getConnection()
.createStanzaCollectorAndSend(focusInviteIQ);
collector.nextResultOrThrow();
}
Expand Down Expand Up @@ -1687,4 +1700,52 @@ private XMPPConnection getConnection()

return null;
}

/**
* Handles mute requests received by jicofo if enabled.
*/
private class MuteIqHandler
extends AbstractIqRequestHandler
{
MuteIqHandler()
{
super(
MuteIq.ELEMENT_NAME,
MuteIq.NAMESPACE,
IQ.Type.set,
Mode.sync);
}

@Override
public IQ handleIQRequest(IQ iqRequest)
{
return handleMuteIq((MuteIq) iqRequest);
}

/**
* Handles the incoming mute request only if it is from the focus.
* @param muteIq the incoming iq.
* @return the result iq.
*/
private IQ handleMuteIq(MuteIq muteIq)
{
Boolean doMute = muteIq.getMute();
Jid from = muteIq.getFrom();

if (doMute == null
|| !from.getResourceOrEmpty().equals(
gatewaySession.getFocusResourceAddr()))
{
return IQ.createErrorResponse(muteIq, XMPPError.getBuilder(
XMPPError.Condition.item_not_found));
}

if (doMute)
{
gatewaySession.mute();
}

return IQ.createResultIQ(muteIq);
}
}
}
Loading

0 comments on commit 0798301

Please sign in to comment.