Merge remote-tracking branch 'upstream/master' into html5-stun-audio

This commit is contained in:
Matthew Marangoni 2016-10-24 09:08:13 -07:00
commit 0d3f231ac1
194 changed files with 2797 additions and 7385 deletions

View File

@ -55,7 +55,7 @@ libraryDependencies ++= {
"org.pegdown" % "pegdown" % "1.4.0", "org.pegdown" % "pegdown" % "1.4.0",
"junit" % "junit" % "4.11", "junit" % "junit" % "4.11",
"com.etaty.rediscala" %% "rediscala" % "1.4.0", "com.etaty.rediscala" %% "rediscala" % "1.4.0",
"commons-codec" % "commons-codec" % "1.8", "commons-codec" % "commons-codec" % "1.10",
"joda-time" % "joda-time" % "2.3", "joda-time" % "joda-time" % "2.3",
"com.google.code.gson" % "gson" % "2.5", "com.google.code.gson" % "gson" % "2.5",
"redis.clients" % "jedis" % "2.7.2", "redis.clients" % "jedis" % "2.7.2",

View File

@ -59,49 +59,50 @@ public class MeetingMessageReceiver implements MessageHandler {
EndMeetingMessage emm = (EndMeetingMessage) msg; EndMeetingMessage emm = (EndMeetingMessage) msg;
bbbGW.endMeeting(emm.meetingId); bbbGW.endMeeting(emm.meetingId);
} else if (msg instanceof RegisterUserMessage) { } else if (msg instanceof RegisterUserMessage) {
RegisterUserMessage emm = (RegisterUserMessage) msg; RegisterUserMessage rum = (RegisterUserMessage) msg;
bbbGW.registerUser(emm.meetingID, emm.internalUserId, emm.fullname, emm.role, emm.externUserID, emm.authToken, emm.avatarURL); bbbGW.registerUser(rum.meetingID, rum.internalUserId, rum.fullname, rum.role, rum.externUserID, rum.authToken, rum.avatarURL);
} else if (msg instanceof DestroyMeetingMessage) { } else if (msg instanceof DestroyMeetingMessage) {
DestroyMeetingMessage emm = (DestroyMeetingMessage) msg; DestroyMeetingMessage dmm = (DestroyMeetingMessage) msg;
bbbGW.destroyMeeting(emm.meetingId); bbbGW.destroyMeeting(dmm.meetingId);
} else if (msg instanceof ValidateAuthTokenMessage) { } else if (msg instanceof ValidateAuthTokenMessage) {
ValidateAuthTokenMessage emm = (ValidateAuthTokenMessage) msg; ValidateAuthTokenMessage vam = (ValidateAuthTokenMessage) msg;
String sessionId = "tobeimplemented"; String sessionId = "tobeimplemented";
bbbGW.validateAuthToken(emm.meetingId, emm.userId, emm.token, emm.replyTo, sessionId); bbbGW.validateAuthToken(vam.meetingId, vam.userId, vam.token, vam.replyTo, sessionId);
} else if (msg instanceof UserConnectedToGlobalAudio) { } else if (msg instanceof UserConnectedToGlobalAudio) {
UserConnectedToGlobalAudio emm = (UserConnectedToGlobalAudio) msg; UserConnectedToGlobalAudio ustga = (UserConnectedToGlobalAudio) msg;
Map<String, Object> logData = new HashMap<String, Object>(); Map<String, Object> logData = new HashMap<String, Object>();
logData.put("voiceConf", emm.voiceConf); logData.put("voiceConf", ustga.voiceConf);
logData.put("userId", emm.userid); logData.put("userId", ustga.userid);
logData.put("username", emm.name); logData.put("username", ustga.name);
logData.put("event", "user_connected_to_global_audio"); logData.put("event", "user_connected_to_global_audio");
logData.put("description", "User connected to global audio."); logData.put("description", "User connected to global audio.");
/*
Gson gson = new Gson(); Gson gson = new Gson();
String logStr = gson.toJson(logData); String logStr = gson.toJson(logData);
System.out.println("User connected to global audio: data={}", logStr);
//System.out.println("User connected to global audio: data={}", logStr); */
bbbGW.userConnectedToGlobalAudio(ustga.voiceConf, ustga.userid, ustga.name);
bbbGW.userConnectedToGlobalAudio(emm.voiceConf, emm.userid, emm.name);
} else if (msg instanceof UserDisconnectedFromGlobalAudio) { } else if (msg instanceof UserDisconnectedFromGlobalAudio) {
UserDisconnectedFromGlobalAudio emm = (UserDisconnectedFromGlobalAudio) msg; UserDisconnectedFromGlobalAudio udfga = (UserDisconnectedFromGlobalAudio) msg;
Map<String, Object> logData = new HashMap<String, Object>(); Map<String, Object> logData = new HashMap<String, Object>();
logData.put("voiceConf", emm.voiceConf); logData.put("voiceConf", udfga.voiceConf);
logData.put("userId", emm.userid); logData.put("userId", udfga.userid);
logData.put("username", emm.name); logData.put("username", udfga.name);
logData.put("event", "user_disconnected_from_global_audio"); logData.put("event", "user_disconnected_from_global_audio");
logData.put("description", "User disconnected from global audio."); logData.put("description", "User disconnected from global audio.");
/*
Gson gson = new Gson(); Gson gson = new Gson();
String logStr = gson.toJson(logData); String logStr = gson.toJson(logData);
System.out.println("User disconnected from global audio: data={}", logStr);
//System.out.println("User disconnected from global audio: data={}", logStr); */
bbbGW.userDisconnectedFromGlobalAudio(emm.voiceConf, emm.userid, emm.name); bbbGW.userDisconnectedFromGlobalAudio(udfga.voiceConf, udfga.userid, udfga.name);
} }
else if (msg instanceof GetAllMeetingsRequest) { else if (msg instanceof GetAllMeetingsRequest) {
GetAllMeetingsRequest emm = (GetAllMeetingsRequest) msg; GetAllMeetingsRequest gamr = (GetAllMeetingsRequest) msg;
bbbGW.getAllMeetings("no_need_of_a_meeting_id"); bbbGW.getAllMeetings("no_need_of_a_meeting_id");
} else { } else {
System.out.println("Unknown message: [" + message + "]"); System.out.println("Unknown message: [" + message + "]");
@ -126,8 +127,8 @@ public class MeetingMessageReceiver implements MessageHandler {
if (msg != null) { if (msg != null) {
if (msg instanceof KeepAliveMessage) { if (msg instanceof KeepAliveMessage) {
KeepAliveMessage emm = (KeepAliveMessage) msg; KeepAliveMessage kam = (KeepAliveMessage) msg;
bbbGW.isAliveAudit(emm.keepAliveId); bbbGW.isAliveAudit(kam.keepAliveId);
} }
} else { } else {
System.out.println("Unknown message: [" + message + "]"); System.out.println("Unknown message: [" + message + "]");

View File

@ -29,6 +29,10 @@ public class ParticipantJoinRecordEvent extends AbstractParticipantRecordEvent {
eventMap.put("userId", userId); eventMap.put("userId", userId);
} }
public void setExternalUserId(String externalUserId) {
eventMap.put("externalUserId", externalUserId);
}
public void setName(String name){ public void setName(String name){
eventMap.put("name",name); eventMap.put("name",name);
} }

View File

@ -21,6 +21,7 @@ package org.bigbluebutton.core.recorders.events;
public class PublicChatRecordEvent extends AbstractChatRecordEvent { public class PublicChatRecordEvent extends AbstractChatRecordEvent {
private static final String SENDER = "sender"; private static final String SENDER = "sender";
private static final String SENDERID = "senderId";
private static final String MESSAGE = "message"; private static final String MESSAGE = "message";
private static final String COLOR = "color"; private static final String COLOR = "color";
@ -33,6 +34,10 @@ public class PublicChatRecordEvent extends AbstractChatRecordEvent {
eventMap.put(SENDER, sender); eventMap.put(SENDER, sender);
} }
public void setSenderId(String senderId) {
eventMap.put(SENDERID, senderId);
}
public void setMessage(String message) { public void setMessage(String message) {
eventMap.put(MESSAGE, message); eventMap.put(MESSAGE, message);
} }

View File

@ -43,7 +43,6 @@ http {
services { services {
bbbWebAPI = "http://192.168.23.33/bigbluebutton/api" bbbWebAPI = "http://192.168.23.33/bigbluebutton/api"
sharedSecret = "changeme" sharedSecret = "changeme"
defaultPresentationURL = "http://localhost/default.pdf"
} }
red5 { red5 {

View File

@ -18,7 +18,6 @@ trait SystemConfiguration {
lazy val bbbWebSharedSecret = Try(config.getString("services.sharedSecret")).getOrElse("changeme") lazy val bbbWebSharedSecret = Try(config.getString("services.sharedSecret")).getOrElse("changeme")
lazy val bbbWebModeratorPassword = Try(config.getString("services.moderatorPassword")).getOrElse("changeme") lazy val bbbWebModeratorPassword = Try(config.getString("services.moderatorPassword")).getOrElse("changeme")
lazy val bbbWebViewerPassword = Try(config.getString("services.viewerPassword")).getOrElse("changeme") lazy val bbbWebViewerPassword = Try(config.getString("services.viewerPassword")).getOrElse("changeme")
lazy val bbbWebDefaultPresentationURL = Try(config.getString("services.defaultPresentationURL")).getOrElse("changeme")
lazy val keysExpiresInSec = Try(config.getInt("redis.keyExpiry")).getOrElse(14 * 86400) // 14 days lazy val keysExpiresInSec = Try(config.getInt("redis.keyExpiry")).getOrElse(14 * 86400) // 14 days
lazy val red5DeskShareIP = Try(config.getString("red5.deskshareip")).getOrElse("127.0.0.1") lazy val red5DeskShareIP = Try(config.getString("red5.deskshareip")).getOrElse("127.0.0.1")
lazy val red5DeskShareApp = Try(config.getString("red5.deskshareapp")).getOrElse("") lazy val red5DeskShareApp = Try(config.getString("red5.deskshareapp")).getOrElse("")

View File

@ -117,9 +117,9 @@ class BigBlueButtonActor(val system: ActorSystem,
meetings -= msg.meetingID meetings -= msg.meetingID
log.info("Kick everyone out on meetingId={}", msg.meetingID) log.info("Kick everyone out on meetingId={}", msg.meetingID)
if (m.mProps.isBreakout) { if (m.mProps.isBreakout) {
log.info("Informing parent meeting {} that a breakout room has been ended {}", m.mProps.externalMeetingID, m.mProps.meetingID) log.info("Informing parent meeting {} that a breakout room has been ended {}", m.mProps.parentMeetingID, m.mProps.meetingID)
eventBus.publish(BigBlueButtonEvent(m.mProps.externalMeetingID, eventBus.publish(BigBlueButtonEvent(m.mProps.parentMeetingID,
BreakoutRoomEnded(m.mProps.externalMeetingID, m.mProps.meetingID))) BreakoutRoomEnded(m.mProps.parentMeetingID, m.mProps.meetingID)))
} }
outGW.send(new EndAndKickAll(msg.meetingID, m.mProps.recorded)) outGW.send(new EndAndKickAll(msg.meetingID, m.mProps.recorded))
outGW.send(new DisconnectAllUsers(msg.meetingID)) outGW.send(new DisconnectAllUsers(msg.meetingID))
@ -149,9 +149,9 @@ class BigBlueButtonActor(val system: ActorSystem,
eventBus.subscribe(m.actorRef, m.mProps.deskshareBridge) eventBus.subscribe(m.actorRef, m.mProps.deskshareBridge)
meetings += m.mProps.meetingID -> m meetings += m.mProps.meetingID -> m
outGW.send(new MeetingCreated(m.mProps.meetingID, m.mProps.externalMeetingID, m.mProps.recorded, m.mProps.meetingName, outGW.send(new MeetingCreated(m.mProps.meetingID, m.mProps.externalMeetingID, m.mProps.parentMeetingID,
m.mProps.voiceBridge, msg.mProps.duration, msg.mProps.moderatorPass, m.mProps.recorded, m.mProps.meetingName, m.mProps.voiceBridge, msg.mProps.duration, msg.mProps.moderatorPass,
msg.mProps.viewerPass, msg.mProps.createTime, msg.mProps.createDate)) msg.mProps.viewerPass, msg.mProps.createTime, msg.mProps.createDate, msg.mProps.isBreakout))
m.actorRef ! new InitializeMeeting(m.mProps.meetingID, m.mProps.recorded) m.actorRef ! new InitializeMeeting(m.mProps.meetingID, m.mProps.recorded)
} }

View File

@ -57,6 +57,7 @@ class BigBlueButtonInGW(
val mProps = new MeetingProperties( val mProps = new MeetingProperties(
msg.payload.id, msg.payload.id,
msg.payload.externalId, msg.payload.externalId,
msg.payload.parentId,
msg.payload.name, msg.payload.name,
msg.payload.record, msg.payload.record,
msg.payload.voiceConfId, msg.payload.voiceConfId,
@ -69,7 +70,8 @@ class BigBlueButtonInGW(
msg.payload.createTime, msg.payload.createTime,
msg.payload.createDate, msg.payload.createDate,
red5DeskShareIP, red5DeskShareApp, red5DeskShareIP, red5DeskShareApp,
msg.payload.isBreakout) msg.payload.isBreakout,
msg.payload.sequence)
eventBus.publish(BigBlueButtonEvent("meeting-manager", new CreateMeeting(msg.payload.id, mProps))) eventBus.publish(BigBlueButtonEvent("meeting-manager", new CreateMeeting(msg.payload.id, mProps)))
} }

View File

@ -52,13 +52,13 @@ class JsonMessageSenderActor(val service: MessageSender)
// Breakout // Breakout
private def handleBreakoutRoomStarted(msg: BreakoutRoomStartedOutMessage) { private def handleBreakoutRoomStarted(msg: BreakoutRoomStartedOutMessage) {
val payload = new BreakoutRoomPayload(msg.meetingId, msg.breakout.breakoutId, msg.breakout.name) val payload = new BreakoutRoomPayload(msg.parentMeetingId, msg.breakout.meetingId, msg.breakout.externalMeetingId, msg.breakout.name, msg.breakout.sequence)
val request = new BreakoutRoomStarted(payload) val request = new BreakoutRoomStarted(payload)
service.send(MessagingConstants.FROM_MEETING_CHANNEL, request.toJson) service.send(MessagingConstants.FROM_MEETING_CHANNEL, request.toJson)
} }
private def handleBreakoutRoomEnded(msg: BreakoutRoomEndedOutMessage) { private def handleBreakoutRoomEnded(msg: BreakoutRoomEndedOutMessage) {
val payload = new BreakoutRoomPayload(msg.meetingId, msg.breakoutId, "") val payload = new BreakoutRoomPayload(msg.parentMeetingId, msg.meetingId, "", "", 0)
val request = new BreakoutRoomClosed(payload) val request = new BreakoutRoomClosed(payload)
service.send(MessagingConstants.FROM_MEETING_CHANNEL, request.toJson) service.send(MessagingConstants.FROM_MEETING_CHANNEL, request.toJson)
} }
@ -66,7 +66,7 @@ class JsonMessageSenderActor(val service: MessageSender)
private def handleUpdateBreakoutUsers(msg: UpdateBreakoutUsersOutMessage) { private def handleUpdateBreakoutUsers(msg: UpdateBreakoutUsersOutMessage) {
val users = new java.util.ArrayList[BreakoutUserPayload]() val users = new java.util.ArrayList[BreakoutUserPayload]()
msg.users.foreach(x => users.add(new BreakoutUserPayload(x.id, x.name))) msg.users.foreach(x => users.add(new BreakoutUserPayload(x.id, x.name)))
val payload = new UpdateBreakoutUsersPayload(msg.meetingId, msg.breakoutId, users) val payload = new UpdateBreakoutUsersPayload(msg.parentMeetingId, msg.breakoutMeetingId, users)
val request = new UpdateBreakoutUsers(payload) val request = new UpdateBreakoutUsers(payload)
service.send(MessagingConstants.FROM_MEETING_CHANNEL, request.toJson()) service.send(MessagingConstants.FROM_MEETING_CHANNEL, request.toJson())
} }
@ -85,29 +85,29 @@ class JsonMessageSenderActor(val service: MessageSender)
private def handleBreakoutRoomsList(msg: BreakoutRoomsListOutMessage) { private def handleBreakoutRoomsList(msg: BreakoutRoomsListOutMessage) {
val rooms = new java.util.ArrayList[BreakoutRoomPayload]() val rooms = new java.util.ArrayList[BreakoutRoomPayload]()
msg.rooms.foreach(r => rooms.add(new BreakoutRoomPayload(msg.meetingId, r.breakoutId, r.name))) msg.rooms.foreach(r => rooms.add(new BreakoutRoomPayload(msg.meetingId, r.meetingId, r.externalMeetingId, r.name, r.sequence)))
val payload = new BreakoutRoomsListPayload(msg.meetingId, rooms, msg.roomsReady) val payload = new BreakoutRoomsListPayload(msg.meetingId, rooms, msg.roomsReady)
val request = new BreakoutRoomsList(payload) val request = new BreakoutRoomsList(payload)
service.send(MessagingConstants.FROM_MEETING_CHANNEL, request.toJson()) service.send(MessagingConstants.FROM_MEETING_CHANNEL, request.toJson())
} }
private def handleCreateBreakoutRoom(msg: CreateBreakoutRoom) { private def handleCreateBreakoutRoom(msg: CreateBreakoutRoom) {
val payload = new CreateBreakoutRoomRequestPayload(msg.room.breakoutId, msg.room.parentId, msg.room.name, val payload = new CreateBreakoutRoomRequestPayload(msg.room.breakoutMeetingId, msg.room.parentId, msg.room.name,
msg.room.voiceConfId, msg.room.viewerPassword, msg.room.moderatorPassword, msg.room.sequence, msg.room.voiceConfId, msg.room.viewerPassword, msg.room.moderatorPassword,
msg.room.durationInMinutes, msg.room.defaultPresentationURL, msg.room.record) msg.room.durationInMinutes, msg.room.sourcePresentationId, msg.room.sourcePresentationSlide, msg.room.record)
val request = new CreateBreakoutRoomRequest(payload) val request = new CreateBreakoutRoomRequest(payload)
service.send(MessagingConstants.FROM_MEETING_CHANNEL, request.toJson()) service.send(MessagingConstants.FROM_MEETING_CHANNEL, request.toJson())
} }
private def handleEndBreakoutRoom(msg: EndBreakoutRoom) { private def handleEndBreakoutRoom(msg: EndBreakoutRoom) {
val payload = new EndBreakoutRoomRequestPayload(msg.breakoutId) val payload = new EndBreakoutRoomRequestPayload(msg.breakoutMeetingId)
val request = new EndBreakoutRoomRequest(payload) val request = new EndBreakoutRoomRequest(payload)
service.send(MessagingConstants.FROM_MEETING_CHANNEL, request.toJson()) service.send(MessagingConstants.FROM_MEETING_CHANNEL, request.toJson())
} }
def handleBreakoutRoomJoinURL(msg: BreakoutRoomJoinURLOutMessage) { def handleBreakoutRoomJoinURL(msg: BreakoutRoomJoinURLOutMessage) {
val payload = new BreakoutRoomJoinURLPayload(msg.meetingId, val payload = new BreakoutRoomJoinURLPayload(msg.parentMeetingId,
msg.breakoutId, msg.userId, msg.joinURL) msg.breakoutMeetingId, msg.userId, msg.joinURL)
val request = new BreakoutRoomJoinURL(payload) val request = new BreakoutRoomJoinURL(payload)
service.send(MessagingConstants.FROM_MEETING_CHANNEL, request.toJson) service.send(MessagingConstants.FROM_MEETING_CHANNEL, request.toJson)
} }

View File

@ -56,7 +56,7 @@ class LiveMeeting(val mProps: MeetingProperties,
} }
def startCheckingIfWeNeedToEndVoiceConf() { def startCheckingIfWeNeedToEndVoiceConf() {
if (usersModel.numWebUsers == 0) { if (usersModel.numWebUsers == 0 && !mProps.isBreakout) {
meetingModel.lastWebUserLeft() meetingModel.lastWebUserLeft()
log.debug("MonitorNumberOfWebUsers started for meeting [" + mProps.meetingID + "]") log.debug("MonitorNumberOfWebUsers started for meeting [" + mProps.meetingID + "]")
} }
@ -117,7 +117,7 @@ class LiveMeeting(val mProps: MeetingProperties,
meetingModel.meetingHasEnded meetingModel.meetingHasEnded
/** /**
* See if this meeting has breakout rooms. If so, we also need to end them. * Check if this meeting has breakout rooms. If so, we also need to end them.
*/ */
handleEndAllBreakoutRooms(new EndAllBreakoutRooms(msg.meetingId)) handleEndAllBreakoutRooms(new EndAllBreakoutRooms(msg.meetingId))

View File

@ -37,8 +37,8 @@ class MeetingActorInternal(val mProps: MeetingProperties,
if (mProps.isBreakout) { if (mProps.isBreakout) {
// This is a breakout room. Inform our parent meeting that we have been successfully created. // This is a breakout room. Inform our parent meeting that we have been successfully created.
eventBus.publish(BigBlueButtonEvent( eventBus.publish(BigBlueButtonEvent(
mProps.externalMeetingID, mProps.parentMeetingID,
BreakoutRoomCreated(mProps.externalMeetingID, mProps.meetingID))) BreakoutRoomCreated(mProps.parentMeetingID, mProps.meetingID)))
} }
def receive = { def receive = {

View File

@ -4,10 +4,11 @@ import org.bigbluebutton.core.api.Permissions
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
case object StopMeetingActor case object StopMeetingActor
case class MeetingProperties(meetingID: String, externalMeetingID: String, meetingName: String, recorded: Boolean, case class MeetingProperties(meetingID: String, externalMeetingID: String, parentMeetingID: String, meetingName: String,
voiceBridge: String, deskshareBridge: String, duration: Int, autoStartRecording: Boolean, recorded: Boolean, voiceBridge: String, deskshareBridge: String, duration: Int,
allowStartStopRecording: Boolean, moderatorPass: String, viewerPass: String, createTime: Long, autoStartRecording: Boolean, allowStartStopRecording: Boolean, moderatorPass: String,
createDate: String, red5DeskShareIP: String, red5DeskShareApp: String, isBreakout: Boolean) viewerPass: String, createTime: Long, createDate: String,
red5DeskShareIP: String, red5DeskShareApp: String, isBreakout: Boolean, sequence: Int)
case class MeetingExtensionProp(maxExtensions: Int = 2, numExtensions: Int = 0, extendByMinutes: Int = 20, case class MeetingExtensionProp(maxExtensions: Int = 2, numExtensions: Int = 0, extendByMinutes: Int = 20,
sendNotice: Boolean = true, sent15MinNotice: Boolean = false, sendNotice: Boolean = true, sent15MinNotice: Boolean = false,

View File

@ -44,7 +44,6 @@ class MessageSenderActor(val service: MessageSender)
extends Actor with ActorLogging { extends Actor with ActorLogging {
val encoder = new ToJsonEncoder() val encoder = new ToJsonEncoder()
def receive = { def receive = {
case msg: UserEjectedFromMeeting => handleUserEjectedFromMeeting(msg) case msg: UserEjectedFromMeeting => handleUserEjectedFromMeeting(msg)
case msg: GetChatHistoryReply => handleGetChatHistoryReply(msg) case msg: GetChatHistoryReply => handleGetChatHistoryReply(msg)

View File

@ -24,17 +24,16 @@ object UserMessagesProtocol extends DefaultJsonProtocol {
} }
} }
implicit val breakoutRoomInPayloadFormat = jsonFormat2(BreakoutRoomInPayload) implicit val breakoutRoomInPayloadFormat = jsonFormat3(BreakoutRoomInPayload)
implicit val createBreakoutRoomsFormat = jsonFormat4(CreateBreakoutRooms) implicit val createBreakoutRoomsFormat = jsonFormat5(CreateBreakoutRooms)
implicit val breakoutRoomsListMessageFormat = jsonFormat1(BreakoutRoomsListMessage) implicit val breakoutRoomsListMessageFormat = jsonFormat1(BreakoutRoomsListMessage)
implicit val requestBreakoutJoinURLInMessageFormat = jsonFormat3(RequestBreakoutJoinURLInMessage) implicit val requestBreakoutJoinURLInMessageFormat = jsonFormat4(RequestBreakoutJoinURLInMessage)
implicit val transferUserToMeetingRequestFormat = jsonFormat3(TransferUserToMeetingRequest) implicit val transferUserToMeetingRequestFormat = jsonFormat3(TransferUserToMeetingRequest)
implicit val endBreakoutRoomsFormat = jsonFormat1(EndAllBreakoutRooms) implicit val endBreakoutRoomsFormat = jsonFormat1(EndAllBreakoutRooms)
implicit val inMsgHeaderFormat = jsonFormat1(InMessageHeader) implicit val inMsgHeaderFormat = jsonFormat1(InMessageHeader)
implicit val outMsgHeaderFormat = jsonFormat1(OutMsgHeader) implicit val outMsgHeaderFormat = jsonFormat1(OutMsgHeader)
implicit val outMsgEnvelopeHeaderFormat = jsonFormat2(OutMsgEnvelopeHeader) implicit val outMsgEnvelopeHeaderFormat = jsonFormat2(OutMsgEnvelopeHeader)
implicit val createBreakoutRoomOutMsgPayloadFormat = jsonFormat8(CreateBreakoutRoomOutMsgPayload) implicit val createBreakoutRoomOutMsgPayloadFormat = jsonFormat11(CreateBreakoutRoomOutMsgPayload)
implicit val createBreakoutRoomOutMsgEnvelopePayloadFormat = jsonFormat2(CreateBreakoutRoomOutMsgEnvelopePayload) implicit val createBreakoutRoomOutMsgEnvelopePayloadFormat = jsonFormat2(CreateBreakoutRoomOutMsgEnvelopePayload)
implicit val createBreakoutRoomOutMsgEnvelopeFormat = jsonFormat2(CreateBreakoutRoomOutMsgEnvelope) implicit val createBreakoutRoomOutMsgEnvelopeFormat = jsonFormat2(CreateBreakoutRoomOutMsgEnvelope)
} }

View File

@ -5,12 +5,9 @@ case class OutMsgEnvelopeHeader(`type`: MessageType.MessageType, address: String
trait OutMessage trait OutMessage
case class CreateBreakoutRoomOutMsgEnvelope(header: OutMsgEnvelopeHeader, case class CreateBreakoutRoomOutMsgEnvelope(header: OutMsgEnvelopeHeader, payload: CreateBreakoutRoomOutMsgEnvelopePayload)
payload: CreateBreakoutRoomOutMsgEnvelopePayload) case class CreateBreakoutRoomOutMsgEnvelopePayload(header: OutMsgHeader, payload: CreateBreakoutRoomOutMsgPayload)
case class CreateBreakoutRoomOutMsgEnvelopePayload(header: OutMsgHeader, case class CreateBreakoutRoomOutMsgPayload(meetingId: String, parentId: String, name: String,
payload: CreateBreakoutRoomOutMsgPayload) voiceConfId: String, moderatorPassword: String, viewerPassword: String,
case class CreateBreakoutRoomOutMsgPayload(breakoutId: String, name: String, parentId: String, durationInMinutes: Int, sourcePresentationId: String, sourcePresentationSlide: Int,
voiceConfId: String, durationInMinutes: Int, record: Boolean, sequence: Int)
moderatorPassword: String, viewerPassword: String,
defaultPresentationUrl: String)

View File

@ -86,6 +86,7 @@ class RecorderActor(val recorder: RecorderApplication)
ev.setTimestamp(TimestampGenerator.generateTimestamp); ev.setTimestamp(TimestampGenerator.generateTimestamp);
ev.setMeetingId(msg.meetingID); ev.setMeetingId(msg.meetingID);
ev.setSender(message.get("fromUsername")); ev.setSender(message.get("fromUsername"));
ev.setSenderId(message.get("fromUserID"));
ev.setMessage(message.get("message")); ev.setMessage(message.get("message"));
ev.setColor(message.get("fromColor")); ev.setColor(message.get("fromColor"));
recorder.record(msg.meetingID, ev); recorder.record(msg.meetingID, ev);
@ -196,6 +197,7 @@ class RecorderActor(val recorder: RecorderApplication)
val ev = new ParticipantJoinRecordEvent(); val ev = new ParticipantJoinRecordEvent();
ev.setTimestamp(TimestampGenerator.generateTimestamp); ev.setTimestamp(TimestampGenerator.generateTimestamp);
ev.setUserId(msg.user.userID); ev.setUserId(msg.user.userID);
ev.setExternalUserId(msg.user.externUserID);
ev.setName(msg.user.name); ev.setName(msg.user.name);
ev.setMeetingId(msg.meetingID); ev.setMeetingId(msg.meetingID);
ev.setRole(msg.user.role.toString()); ev.setRole(msg.user.role.toString());

View File

@ -6,6 +6,8 @@ object Constants {
val PAYLOAD = "payload" val PAYLOAD = "payload"
val MEETING_ID = "meeting_id" val MEETING_ID = "meeting_id"
val EXTERNAL_MEETING_ID = "external_meeting_id" val EXTERNAL_MEETING_ID = "external_meeting_id"
val PARENT_MEETING_ID = "parent_meeting_id"
val IS_BREAKOUT = "is_breakout";
val TIMESTAMP = "timestamp" val TIMESTAMP = "timestamp"
val CURRENT_TIME = "current_time" val CURRENT_TIME = "current_time"
val USER_ID = "userid" val USER_ID = "userid"

View File

@ -42,17 +42,14 @@ case class LockSetting(meetingID: String, locked: Boolean, settings: Map[String,
// Sent by user to request the breakout rooms list of a room // Sent by user to request the breakout rooms list of a room
case class BreakoutRoomsListMessage(meetingId: String) extends InMessage case class BreakoutRoomsListMessage(meetingId: String) extends InMessage
// Sent by user to request creation of breakout rooms // Sent by user to request creation of breakout rooms
case class CreateBreakoutRooms(meetingId: String, durationInMinutes: Int, record: Boolean, case class CreateBreakoutRooms(meetingId: String, durationInMinutes: Int, record: Boolean, redirectOnJoin: Boolean, rooms: Vector[BreakoutRoomInPayload]) extends InMessage
rooms: Vector[BreakoutRoomInPayload]) extends InMessage case class BreakoutRoomInPayload(name: String, sequence: Int, users: Vector[String])
case class BreakoutRoomInPayload(name: String, users: Vector[String])
// Sent by user to request for a join URL in order to be able to join a breakout room // Sent by user to request for a join URL in order to be able to join a breakout room
case class RequestBreakoutJoinURLInMessage(meetingId: String, breakoutId: String, case class RequestBreakoutJoinURLInMessage(meetingId: String, breakoutMeetingId: String, userId: String, redirect: Boolean) extends InMessage
userId: String) extends InMessage
// Sent by breakout actor to tell meeting actor that breakout room has been created. // Sent by breakout actor to tell meeting actor that breakout room has been created.
case class BreakoutRoomCreated(meetingId: String, breakoutRoomId: String) extends InMessage case class BreakoutRoomCreated(meetingId: String, breakoutRoomId: String) extends InMessage
// Sent by breakout actor to tell meeting actor the list of users in the breakout room. // Sent by breakout actor to tell meeting actor the list of users in the breakout room.
case class BreakoutRoomUsersUpdate(meetingId: String, breakoutId: String, case class BreakoutRoomUsersUpdate(meetingId: String, breakoutMeetingId: String, users: Vector[BreakoutUser]) extends InMessage
users: Vector[BreakoutUser]) extends InMessage
// Send by internal actor to tell the breakout actor to send it's list of users to the main meeting actor. // Send by internal actor to tell the breakout actor to send it's list of users to the main meeting actor.
case class SendBreakoutUsersUpdate(meetingId: String) extends InMessage case class SendBreakoutUsersUpdate(meetingId: String) extends InMessage
// Sent by user to request ending all the breakout rooms // Sent by user to request ending all the breakout rooms

View File

@ -14,8 +14,8 @@ case class VoiceRecordingStarted(meetingID: String, recorded: Boolean, recording
case class VoiceRecordingStopped(meetingID: String, recorded: Boolean, recordingFile: String, timestamp: String, confNum: String) extends IOutMessage case class VoiceRecordingStopped(meetingID: String, recorded: Boolean, recordingFile: String, timestamp: String, confNum: String) extends IOutMessage
case class RecordingStatusChanged(meetingID: String, recorded: Boolean, userId: String, recording: Boolean) extends IOutMessage case class RecordingStatusChanged(meetingID: String, recorded: Boolean, userId: String, recording: Boolean) extends IOutMessage
case class GetRecordingStatusReply(meetingID: String, recorded: Boolean, userId: String, recording: Boolean) extends IOutMessage case class GetRecordingStatusReply(meetingID: String, recorded: Boolean, userId: String, recording: Boolean) extends IOutMessage
case class MeetingCreated(meetingID: String, externalMeetingID: String, recorded: Boolean, name: String, case class MeetingCreated(meetingID: String, externalMeetingID: String, parentMeetingID: String, recorded: Boolean, name: String,
voiceBridge: String, duration: Int, moderatorPass: String, viewerPass: String, createTime: Long, createDate: String) extends IOutMessage voiceBridge: String, duration: Int, moderatorPass: String, viewerPass: String, createTime: Long, createDate: String, isBreakout: Boolean) extends IOutMessage
case class MeetingMuted(meetingID: String, recorded: Boolean, meetingMuted: Boolean) extends IOutMessage case class MeetingMuted(meetingID: String, recorded: Boolean, meetingMuted: Boolean) extends IOutMessage
case class MeetingEnded(meetingID: String, recorded: Boolean, voiceBridge: String) extends IOutMessage case class MeetingEnded(meetingID: String, recorded: Boolean, voiceBridge: String) extends IOutMessage
case class MeetingState(meetingID: String, recorded: Boolean, userId: String, permissions: Permissions, meetingMuted: Boolean) extends IOutMessage case class MeetingState(meetingID: String, recorded: Boolean, userId: String, permissions: Permissions, meetingMuted: Boolean) extends IOutMessage
@ -30,17 +30,17 @@ case object IsAliveMessage extends IOutMessage
// Breakout Rooms // Breakout Rooms
case class BreakoutRoomsListOutMessage(meetingId: String, rooms: Vector[BreakoutRoomBody], roomsReady: Boolean) extends IOutMessage case class BreakoutRoomsListOutMessage(meetingId: String, rooms: Vector[BreakoutRoomBody], roomsReady: Boolean) extends IOutMessage
case class CreateBreakoutRoom(meetingId: String, room: BreakoutRoomOutPayload) extends IOutMessage case class CreateBreakoutRoom(meetingId: String, room: BreakoutRoomOutPayload) extends IOutMessage
case class EndBreakoutRoom(breakoutId: String) extends IOutMessage case class EndBreakoutRoom(breakoutMeetingId: String) extends IOutMessage
case class BreakoutRoomOutPayload(breakoutId: String, name: String, parentId: String, case class BreakoutRoomOutPayload(breakoutMeetingId: String, name: String, parentId: String, sequence: Integer,
voiceConfId: String, durationInMinutes: Int, moderatorPassword: String, viewerPassword: String, voiceConfId: String, durationInMinutes: Int, moderatorPassword: String, viewerPassword: String,
defaultPresentationURL: String, record: Boolean) sourcePresentationId: String, sourcePresentationSlide: Int, record: Boolean)
case class BreakoutRoomJoinURLOutMessage(meetingId: String, recorded: Boolean, breakoutId: String, userId: String, joinURL: String) extends IOutMessage case class BreakoutRoomJoinURLOutMessage(parentMeetingId: String, recorded: Boolean, breakoutMeetingId: String, userId: String, joinURL: String) extends IOutMessage
case class BreakoutRoomStartedOutMessage(meetingId: String, recorded: Boolean, breakout: BreakoutRoomBody) extends IOutMessage case class BreakoutRoomStartedOutMessage(parentMeetingId: String, recorded: Boolean, breakout: BreakoutRoomBody) extends IOutMessage
case class BreakoutRoomBody(name: String, breakoutId: String) case class BreakoutRoomBody(name: String, externalMeetingId: String, meetingId: String, sequence: Int)
case class UpdateBreakoutUsersOutMessage(meetingId: String, recorded: Boolean, breakoutId: String, users: Vector[BreakoutUser]) extends IOutMessage case class UpdateBreakoutUsersOutMessage(parentMeetingId: String, recorded: Boolean, breakoutMeetingId: String, users: Vector[BreakoutUser]) extends IOutMessage
case class MeetingTimeRemainingUpdate(meetingId: String, recorded: Boolean, timeRemaining: Int) extends IOutMessage case class MeetingTimeRemainingUpdate(meetingId: String, recorded: Boolean, timeRemaining: Int) extends IOutMessage
case class BreakoutRoomsTimeRemainingUpdateOutMessage(meetingId: String, recorded: Boolean, timeRemaining: Int) extends IOutMessage case class BreakoutRoomsTimeRemainingUpdateOutMessage(meetingId: String, recorded: Boolean, timeRemaining: Int) extends IOutMessage
case class BreakoutRoomEndedOutMessage(meetingId: String, breakoutId: String) extends IOutMessage case class BreakoutRoomEndedOutMessage(parentMeetingId: String, meetingId: String) extends IOutMessage
// Permissions // Permissions
case class PermissionsSettingInitialized(meetingID: String, permissions: Permissions, applyTo: Array[UserVO]) extends IOutMessage case class PermissionsSettingInitialized(meetingID: String, permissions: Permissions, applyTo: Array[UserVO]) extends IOutMessage

View File

@ -20,18 +20,11 @@ trait BreakoutRoomApp extends SystemConfiguration {
val outGW: OutMessageGateway val outGW: OutMessageGateway
val eventBus: IncomingEventBus val eventBus: IncomingEventBus
def getDefaultPresentationURL(): String = {
var presURL = bbbWebDefaultPresentationURL
val page = presModel.getCurrentPage()
page foreach { p =>
presURL = BreakoutRoomsUtil.fromSWFtoPDF(p.swfUri)
}
presURL
}
def handleBreakoutRoomsList(msg: BreakoutRoomsListMessage) { def handleBreakoutRoomsList(msg: BreakoutRoomsListMessage) {
val breakoutRooms = breakoutModel.getRooms().toVector map { r => new BreakoutRoomBody(r.name, r.id) } val breakoutRooms = breakoutModel.getRooms().toVector map { r => new BreakoutRoomBody(r.name, r.externalMeetingId, r.id, r.sequence) }
outGW.send(new BreakoutRoomsListOutMessage(mProps.meetingID, breakoutRooms, breakoutModel.pendingRoomsNumber == 0 && breakoutRooms.length > 0)); val roomsReady = breakoutModel.pendingRoomsNumber == 0 && breakoutRooms.length > 0
log.info("Sending breakout rooms list to {} with containing {} room(s)", mProps.meetingID, breakoutRooms.length)
outGW.send(new BreakoutRoomsListOutMessage(mProps.meetingID, breakoutRooms, roomsReady))
} }
def handleCreateBreakoutRooms(msg: CreateBreakoutRooms) { def handleCreateBreakoutRooms(msg: CreateBreakoutRooms) {
@ -40,53 +33,65 @@ trait BreakoutRoomApp extends SystemConfiguration {
log.warning("CreateBreakoutRooms event received while {} are pending to be created for meeting {}", breakoutModel.pendingRoomsNumber, mProps.meetingID) log.warning("CreateBreakoutRooms event received while {} are pending to be created for meeting {}", breakoutModel.pendingRoomsNumber, mProps.meetingID)
return return
} }
if (breakoutModel.getNumberOfRooms() > 0) {
log.warning("CreateBreakoutRooms event received while {} breakout rooms running for meeting {}", breakoutModel.getNumberOfRooms(), mProps.meetingID)
return
}
var i = 0 var i = 0
// in very rare cases the presentation conversion generates an error, what should we do?
// those cases where default.pdf is deleted from the whiteboard
val sourcePresentationId = if (!presModel.getCurrentPresentation().isEmpty) presModel.getCurrentPresentation().get.id else "blank"
val sourcePresentationSlide = if (!presModel.getCurrentPage().isEmpty) presModel.getCurrentPage().get.num else 0
breakoutModel.pendingRoomsNumber = msg.rooms.length; breakoutModel.pendingRoomsNumber = msg.rooms.length;
breakoutModel.redirectOnJoin = msg.redirectOnJoin;
for (room <- msg.rooms) { for (room <- msg.rooms) {
i += 1 i += 1
val presURL = bbbWebDefaultPresentationURL val breakoutMeetingId = BreakoutRoomsUtil.createMeetingIds(mProps.meetingID, i)
val breakoutMeetingId = BreakoutRoomsUtil.createMeetingId(mProps.meetingID, i)
val voiceConfId = BreakoutRoomsUtil.createVoiceConfId(mProps.voiceBridge, i) val voiceConfId = BreakoutRoomsUtil.createVoiceConfId(mProps.voiceBridge, i)
val r = breakoutModel.createBreakoutRoom(breakoutMeetingId, room.name, voiceConfId, room.users, presURL) val r = breakoutModel.createBreakoutRoom(mProps.meetingID, breakoutMeetingId._1, breakoutMeetingId._2, room.name,
val p = new BreakoutRoomOutPayload(r.id, r.name, mProps.meetingID, room.sequence, voiceConfId, room.users)
val p = new BreakoutRoomOutPayload(r.id, r.name, mProps.meetingID, r.sequence,
r.voiceConfId, msg.durationInMinutes, mProps.moderatorPass, mProps.viewerPass, r.voiceConfId, msg.durationInMinutes, mProps.moderatorPass, mProps.viewerPass,
r.defaultPresentationURL, msg.record) sourcePresentationId, sourcePresentationSlide, msg.record)
outGW.send(new CreateBreakoutRoom(mProps.meetingID, p)) outGW.send(new CreateBreakoutRoom(mProps.meetingID, p))
} }
meetingModel.breakoutRoomsdurationInMinutes = msg.durationInMinutes; meetingModel.breakoutRoomsdurationInMinutes = msg.durationInMinutes;
meetingModel.breakoutRoomsStartedOn = timeNowInSeconds; meetingModel.breakoutRoomsStartedOn = timeNowInSeconds;
} }
def sendJoinURL(userId: String, breakoutId: String) { def sendJoinURL(userId: String, externalMeetingId: String, redirect: Boolean) {
log.debug("Sending breakout meeting {} Join URL for user: {}", externalMeetingId, userId);
for { for {
user <- usersModel.getUser(userId) user <- usersModel.getUser(userId)
apiCall = "join" apiCall = "join"
params = BreakoutRoomsUtil.joinParams(user.name, userId, true, breakoutId, mProps.moderatorPass, true) params = BreakoutRoomsUtil.joinParams(user.name, userId, true, externalMeetingId, mProps.moderatorPass, redirect)
baseString = BreakoutRoomsUtil.createBaseString(params) baseString = BreakoutRoomsUtil.createBaseString(params)
checksum = BreakoutRoomsUtil.calculateChecksum(apiCall, baseString, bbbWebSharedSecret) checksum = BreakoutRoomsUtil.calculateChecksum(apiCall, baseString, bbbWebSharedSecret)
joinURL = BreakoutRoomsUtil.createJoinURL(bbbWebAPI, apiCall, baseString, checksum) joinURL = BreakoutRoomsUtil.createJoinURL(bbbWebAPI, apiCall, baseString, checksum)
} yield outGW.send(new BreakoutRoomJoinURLOutMessage(mProps.meetingID, mProps.recorded, breakoutId, userId, joinURL)) } yield outGW.send(new BreakoutRoomJoinURLOutMessage(mProps.meetingID, mProps.recorded, externalMeetingId, userId, joinURL))
} }
def handleRequestBreakoutJoinURL(msg: RequestBreakoutJoinURLInMessage) { def handleRequestBreakoutJoinURL(msg: RequestBreakoutJoinURLInMessage) {
sendJoinURL(msg.userId, msg.breakoutId) sendJoinURL(msg.userId, msg.breakoutMeetingId, msg.redirect)
} }
def handleBreakoutRoomCreated(msg: BreakoutRoomCreated) { def handleBreakoutRoomCreated(msg: BreakoutRoomCreated) {
breakoutModel.pendingRoomsNumber -= 1 breakoutModel.pendingRoomsNumber -= 1
val room = breakoutModel.getBreakoutRoom(msg.breakoutRoomId) val room = breakoutModel.getBreakoutRoom(msg.breakoutRoomId)
room foreach { room => room foreach { room =>
sendBreakoutRoomStarted(mProps.meetingID, room.name, room.id, room.voiceConfId) sendBreakoutRoomStarted(room.parentRoomId, room.name, room.externalMeetingId, room.id, room.sequence, room.voiceConfId)
} }
// We avoid sending invitation // We postpone sending invitation until all breakout rooms have been created
if (breakoutModel.pendingRoomsNumber == 0) { if (breakoutModel.pendingRoomsNumber == 0) {
log.info("All breakout rooms created for meetingId={}", mProps.meetingID) log.info("All breakout rooms created for meetingId={}", mProps.meetingID)
breakoutModel.getRooms().foreach { room => breakoutModel.getRooms().foreach { room =>
breakoutModel.getAssignedUsers(room.id) foreach { users => breakoutModel.getAssignedUsers(room.id) foreach { users =>
users.foreach { u => users.foreach { u =>
log.debug("## Sending Join URL for users: {}", u); log.debug("Sending Join URL for users");
sendJoinURL(u, room.id) sendJoinURL(u, room.externalMeetingId, breakoutModel.redirectOnJoin)
} }
} }
} }
@ -94,8 +99,9 @@ trait BreakoutRoomApp extends SystemConfiguration {
} }
} }
def sendBreakoutRoomStarted(meetingId: String, breakoutName: String, breakoutId: String, voiceConfId: String) { def sendBreakoutRoomStarted(meetingId: String, breakoutName: String, externalMeetingId: String, breakoutMeetingId: String, sequence: Int, voiceConfId: String) {
outGW.send(new BreakoutRoomStartedOutMessage(meetingId, mProps.recorded, new BreakoutRoomBody(breakoutName, breakoutId))) log.info("Sending breakout room started {} for parent meeting {} ", breakoutMeetingId, meetingId);
outGW.send(new BreakoutRoomStartedOutMessage(meetingId, mProps.recorded, new BreakoutRoomBody(breakoutName, externalMeetingId, breakoutMeetingId, sequence)))
} }
def handleBreakoutRoomEnded(msg: BreakoutRoomEnded) { def handleBreakoutRoomEnded(msg: BreakoutRoomEnded) {
@ -104,16 +110,16 @@ trait BreakoutRoomApp extends SystemConfiguration {
} }
def handleBreakoutRoomUsersUpdate(msg: BreakoutRoomUsersUpdate) { def handleBreakoutRoomUsersUpdate(msg: BreakoutRoomUsersUpdate) {
breakoutModel.updateBreakoutUsers(msg.breakoutId, msg.users) foreach { room => breakoutModel.updateBreakoutUsers(msg.breakoutMeetingId, msg.users) foreach { room =>
outGW.send(new UpdateBreakoutUsersOutMessage(mProps.meetingID, mProps.recorded, msg.breakoutId, room.users)) outGW.send(new UpdateBreakoutUsersOutMessage(mProps.meetingID, mProps.recorded, msg.breakoutMeetingId, room.users))
} }
} }
def handleSendBreakoutUsersUpdate(msg: SendBreakoutUsersUpdate) { def handleSendBreakoutUsersUpdate(msg: SendBreakoutUsersUpdate) {
val users = usersModel.getUsers().toVector val users = usersModel.getUsers().toVector
val breakoutUsers = users map { u => new BreakoutUser(u.externUserID, u.name) } val breakoutUsers = users map { u => new BreakoutUser(u.externUserID, u.name) }
eventBus.publish(BigBlueButtonEvent(mProps.externalMeetingID, eventBus.publish(BigBlueButtonEvent(mProps.parentMeetingID,
new BreakoutRoomUsersUpdate(mProps.externalMeetingID, mProps.meetingID, breakoutUsers))) new BreakoutRoomUsersUpdate(mProps.parentMeetingID, mProps.meetingID, breakoutUsers)))
} }
def handleTransferUserToMeeting(msg: TransferUserToMeetingRequest) { def handleTransferUserToMeeting(msg: TransferUserToMeetingRequest) {
@ -152,18 +158,18 @@ trait BreakoutRoomApp extends SystemConfiguration {
} }
object BreakoutRoomsUtil { object BreakoutRoomsUtil {
def createMeetingId(id: String, index: Int): String = { def createMeetingIds(id: String, index: Int): (String, String) = {
id.concat("-").concat(index.toString()) val timeStamp = System.currentTimeMillis()
val externalHash = DigestUtils.sha1Hex(id.concat("-").concat(timeStamp.toString()).concat("-").concat(index.toString()))
val externalId = externalHash.concat("-").concat(timeStamp.toString())
val internalId = DigestUtils.sha1Hex(externalId).concat("-").concat(timeStamp.toString())
(internalId, externalId)
} }
def createVoiceConfId(id: String, index: Int): String = { def createVoiceConfId(id: String, index: Int): String = {
id.concat(index.toString()) id.concat(index.toString())
} }
def fromSWFtoPDF(swfURL: String): String = {
swfURL.replace("swf", "pdf")
}
def createJoinURL(webAPI: String, apiCall: String, baseString: String, checksum: String): String = { def createJoinURL(webAPI: String, apiCall: String, baseString: String, checksum: String): String = {
var apiURL = if (webAPI.endsWith("/")) webAPI else webAPI.concat("/") var apiURL = if (webAPI.endsWith("/")) webAPI else webAPI.concat("/")
apiURL.concat(apiCall).concat("?").concat(baseString).concat("&checksum=").concat(checksum) apiURL.concat(apiCall).concat("?").concat(baseString).concat("&checksum=").concat(checksum)
@ -180,13 +186,13 @@ object BreakoutRoomsUtil {
checksum(apiCall.concat(baseString).concat(sharedSecret)) checksum(apiCall.concat(baseString).concat(sharedSecret))
} }
def joinParams(username: String, userId: String, isBreakout: Boolean, breakoutId: String, def joinParams(username: String, userId: String, isBreakout: Boolean, breakoutMeetingId: String,
password: String, redirect: Boolean): mutable.Map[String, String] = { password: String, redirect: Boolean): mutable.Map[String, String] = {
val params = new collection.mutable.HashMap[String, String] val params = new collection.mutable.HashMap[String, String]
params += "fullName" -> urlEncode(username) params += "fullName" -> urlEncode(username)
params += "userID" -> urlEncode(userId + "-" + breakoutId.substring(breakoutId.lastIndexOf("-") + 1)); params += "userID" -> urlEncode(userId + "-" + breakoutMeetingId.substring(breakoutMeetingId.lastIndexOf("-") + 1));
params += "isBreakout" -> urlEncode(isBreakout.toString()) params += "isBreakout" -> urlEncode(isBreakout.toString())
params += "meetingID" -> urlEncode(breakoutId) params += "meetingID" -> urlEncode(breakoutMeetingId)
params += "password" -> urlEncode(password) params += "password" -> urlEncode(password)
params += "redirect" -> urlEncode(redirect.toString()) params += "redirect" -> urlEncode(redirect.toString())
@ -224,18 +230,4 @@ object BreakoutRoomsUtil {
def urlEncode(s: String): String = { def urlEncode(s: String): String = {
URLEncoder.encode(s, "UTF-8"); URLEncoder.encode(s, "UTF-8");
} }
//
//encodeURIComponent() -- Java encoding similiar to JavaScript encodeURIComponent
//
def encodeURIComponent(component: String): String = {
URLEncoder.encode(component, "UTF-8")
.replaceAll("\\%28", "(")
.replaceAll("\\%29", ")")
.replaceAll("\\+", "%20")
.replaceAll("\\%27", "'")
.replaceAll("\\%21", "!")
.replaceAll("\\%7E", "~")
}
} }

View File

@ -1,16 +1,16 @@
package org.bigbluebutton.core.apps package org.bigbluebutton.core.apps
import scala.collection.mutable.ArrayBuffer import scala.Vector
import scala.collection.immutable.HashMap
case class BreakoutUser(id: String, name: String) case class BreakoutUser(id: String, name: String)
case class BreakoutRoom(id: String, name: String, voiceConfId: String, case class BreakoutRoom(id: String, externalMeetingId: String, name: String, parentRoomId: String, sequence: Integer, voiceConfId: String,
assignedUsers: Vector[String], users: Vector[BreakoutUser], defaultPresentationURL: String) assignedUsers: Vector[String], users: Vector[BreakoutUser])
class BreakoutRoomModel { class BreakoutRoomModel {
private var rooms = new collection.immutable.HashMap[String, BreakoutRoom] private var rooms = new collection.immutable.HashMap[String, BreakoutRoom]
var pendingRoomsNumber: Integer = 0 var pendingRoomsNumber: Integer = 0
var redirectOnJoin: Boolean = false
def add(room: BreakoutRoom): BreakoutRoom = { def add(room: BreakoutRoom): BreakoutRoom = {
rooms += room.id -> room rooms += room.id -> room
@ -21,9 +21,9 @@ class BreakoutRoomModel {
rooms -= id rooms -= id
} }
def createBreakoutRoom(id: String, name: String, voiceConfId: String, def createBreakoutRoom(parentRoomId: String, id: String, externalMeetingId: String, name: String, sequence: Integer, voiceConfId: String,
assignedUsers: Vector[String], defaultPresentationURL: String): BreakoutRoom = { assignedUsers: Vector[String]): BreakoutRoom = {
val room = new BreakoutRoom(id, name, voiceConfId, assignedUsers, Vector(), defaultPresentationURL) val room = new BreakoutRoom(id, externalMeetingId, name, parentRoomId, sequence, voiceConfId, assignedUsers, Vector())
add(room) add(room)
} }
@ -35,18 +35,21 @@ class BreakoutRoomModel {
rooms.values.toArray rooms.values.toArray
} }
def getAssignedUsers(breakoutId: String): Option[Vector[String]] = { def getNumberOfRooms(): Int = {
rooms.size
}
def getAssignedUsers(breakoutMeetingId: String): Option[Vector[String]] = {
for { for {
room <- rooms.get(breakoutId) room <- rooms.get(breakoutMeetingId)
} yield room.assignedUsers } yield room.assignedUsers
} }
def updateBreakoutUsers(breakoutId: String, users: Vector[BreakoutUser]): Option[BreakoutRoom] = { def updateBreakoutUsers(breakoutMeetingId: String, users: Vector[BreakoutUser]): Option[BreakoutRoom] = {
for { for {
room <- rooms.get(breakoutId) room <- rooms.get(breakoutMeetingId)
newroom = room.copy(users = users) newroom = room.copy(users = users)
room2 = add(newroom) room2 = add(newroom)
} yield room2 } yield room2
} }
} }

View File

@ -94,16 +94,10 @@ trait PresentationApp {
} }
def handleGotoSlide(msg: GotoSlide) { def handleGotoSlide(msg: GotoSlide) {
// println("Received GotoSlide for meeting=[" + msg.meetingID + "] page=[" + msg.page + "]")
// println("*** Before change page ****")
// printPresentations
presModel.changePage(msg.page) foreach { page => presModel.changePage(msg.page) foreach { page =>
// println("Switching page for meeting=[" + msg.meetingID + "] page=[" + page.id + "]") log.debug("Switching page for meeting=[{}] page=[{}]", msg.meetingID, page.num);
outGW.send(new GotoSlideOutMsg(mProps.meetingID, mProps.recorded, page)) outGW.send(new GotoSlideOutMsg(mProps.meetingID, mProps.recorded, page))
} }
// println("*** After change page ****")
// printPresentations
usersModel.getCurrentPresenter() foreach { pres => usersModel.getCurrentPresenter() foreach { pres =>
handleStopPollRequest(StopPollRequest(mProps.meetingID, pres.userID)) handleStopPollRequest(StopPollRequest(mProps.meetingID, pres.userID))

View File

@ -29,6 +29,8 @@ object MeetingMessageToJsonConverter {
val payload = new java.util.HashMap[String, Any]() val payload = new java.util.HashMap[String, Any]()
payload.put(Constants.MEETING_ID, msg.meetingID) payload.put(Constants.MEETING_ID, msg.meetingID)
payload.put(Constants.EXTERNAL_MEETING_ID, msg.externalMeetingID) payload.put(Constants.EXTERNAL_MEETING_ID, msg.externalMeetingID)
payload.put(Constants.PARENT_MEETING_ID, msg.parentMeetingID)
payload.put(Constants.IS_BREAKOUT, msg.isBreakout)
payload.put(Constants.NAME, msg.name) payload.put(Constants.NAME, msg.name)
payload.put(Constants.RECORDED, msg.recorded) payload.put(Constants.RECORDED, msg.recorded)
payload.put(Constants.VOICE_CONF, msg.voiceBridge) payload.put(Constants.VOICE_CONF, msg.voiceBridge)
@ -145,8 +147,10 @@ object MeetingMessageToJsonConverter {
def breakoutRoomStartedOutMessageToJson(msg: BreakoutRoomStartedOutMessage): String = { def breakoutRoomStartedOutMessageToJson(msg: BreakoutRoomStartedOutMessage): String = {
val payload = new java.util.HashMap[String, Any]() val payload = new java.util.HashMap[String, Any]()
payload.put("meetingId", msg.meetingId) payload.put("meetingId", msg.breakout.meetingId)
payload.put("breakoutId", msg.breakout.breakoutId) payload.put("externalMeetingId", msg.breakout.externalMeetingId)
payload.put("parentMeetingId", msg.parentMeetingId)
payload.put("sequence", msg.breakout.sequence)
payload.put("name", msg.breakout.name) payload.put("name", msg.breakout.name)
val header = Util.buildHeader(BreakoutRoomStarted.NAME, None) val header = Util.buildHeader(BreakoutRoomStarted.NAME, None)
@ -155,8 +159,8 @@ object MeetingMessageToJsonConverter {
def breakoutRoomEndedOutMessageToJson(msg: BreakoutRoomEndedOutMessage): String = { def breakoutRoomEndedOutMessageToJson(msg: BreakoutRoomEndedOutMessage): String = {
val payload = new java.util.HashMap[String, Any]() val payload = new java.util.HashMap[String, Any]()
payload.put("parentMeetingId", msg.parentMeetingId)
payload.put("meetingId", msg.meetingId) payload.put("meetingId", msg.meetingId)
payload.put("breakoutId", msg.breakoutId)
val header = Util.buildHeader(BreakoutRoomClosed.NAME, None) val header = Util.buildHeader(BreakoutRoomClosed.NAME, None)
Util.buildJson(header, payload) Util.buildJson(header, payload)
@ -164,8 +168,8 @@ object MeetingMessageToJsonConverter {
def breakoutRoomJoinURLOutMessageToJson(msg: BreakoutRoomJoinURLOutMessage): String = { def breakoutRoomJoinURLOutMessageToJson(msg: BreakoutRoomJoinURLOutMessage): String = {
val payload = new java.util.HashMap[String, Any]() val payload = new java.util.HashMap[String, Any]()
payload.put("meetingId", msg.meetingId) payload.put("parentMeetingId", msg.parentMeetingId)
payload.put("breakoutId", msg.breakoutId) payload.put("breakoutMeetingId", msg.breakoutMeetingId)
payload.put("userId", msg.userId) payload.put("userId", msg.userId)
payload.put("joinURL", msg.joinURL) payload.put("joinURL", msg.joinURL)
@ -175,8 +179,8 @@ object MeetingMessageToJsonConverter {
def updateBreakoutUsersOutMessageToJson(msg: UpdateBreakoutUsersOutMessage): String = { def updateBreakoutUsersOutMessageToJson(msg: UpdateBreakoutUsersOutMessage): String = {
val payload = new java.util.HashMap[String, Any]() val payload = new java.util.HashMap[String, Any]()
payload.put("meetingId", msg.meetingId) payload.put("parentMeetingId", msg.parentMeetingId)
payload.put("breakoutId", msg.breakoutId) payload.put("breakoutMeetingId", msg.breakoutMeetingId)
payload.put("recorded", msg.recorded) payload.put("recorded", msg.recorded)
payload.put("users", msg.users.toArray) payload.put("users", msg.users.toArray)

View File

@ -4,6 +4,8 @@ trait AppsTestFixtures {
val meetingId = "testMeetingId" val meetingId = "testMeetingId"
val externalMeetingId = "testExternalMeetingId" val externalMeetingId = "testExternalMeetingId"
val parentMeetingId = "testParentMeetingId"
val sequence = 4
val meetingName = "test meeting" val meetingName = "test meeting"
val record = false val record = false
val voiceConfId = "85115" val voiceConfId = "85115"
@ -16,13 +18,15 @@ trait AppsTestFixtures {
val createTime = System.currentTimeMillis val createTime = System.currentTimeMillis
val createDate = "Oct 26, 2015" val createDate = "Oct 26, 2015"
val isBreakout = false val isBreakout = false
val red5DeskShareIP = "127.0.0.1"
val red5DeskShareApp = "red5App"
val mProps = new MeetingProperties(meetingId, externalMeetingId, val mProps = new MeetingProperties(meetingId, externalMeetingId, parentMeetingId,
meetingName, record, meetingName, record,
voiceConfId, deskshareConfId, voiceConfId, deskshareConfId,
durationInMinutes, durationInMinutes,
autoStartRecording, allowStartStopRecording, autoStartRecording, allowStartStopRecording,
moderatorPassword, viewerPassword, moderatorPassword, viewerPassword,
createTime, createDate, isBreakout) createTime, createDate, red5DeskShareIP, red5DeskShareApp,
isBreakout, sequence)
} }

View File

@ -6,18 +6,11 @@ import org.bigbluebutton.core.UnitSpec
class BreakoutRoomsUtilSpec extends UnitSpec { class BreakoutRoomsUtilSpec extends UnitSpec {
it should "return a pdfURL" in {
val baseURL = "http://localhost/pre1/page1."
val swfURL = baseURL + "swf"
val pdfURL = BreakoutRoomsUtil.fromSWFtoPDF(swfURL)
assert(pdfURL == baseURL + "pdf")
}
it should "return a meetingId" in { it should "return a meetingId" in {
val mainMeetingId = "abc-123" val mainMeetingId = "abc-123"
val index = 1 val index = 1
val result = mainMeetingId.concat("-").concat(index.toString()) val result = mainMeetingId.concat("-").concat(index.toString())
val breakoutMeetingId = BreakoutRoomsUtil.createMeetingId(mainMeetingId, index) val breakoutMeetingId = BreakoutRoomsUtil.createMeetingIds(mainMeetingId, index)
assert(breakoutMeetingId == result) assert(breakoutMeetingId == result)
} }

View File

@ -47,7 +47,7 @@ libraryDependencies ++= {
"org.pegdown" % "pegdown" % "1.4.0", "org.pegdown" % "pegdown" % "1.4.0",
"junit" % "junit" % "4.11", "junit" % "junit" % "4.11",
"com.etaty.rediscala" %% "rediscala" % "1.4.0", "com.etaty.rediscala" %% "rediscala" % "1.4.0",
"commons-codec" % "commons-codec" % "1.8", "commons-codec" % "commons-codec" % "1.10",
"joda-time" % "joda-time" % "2.3", "joda-time" % "joda-time" % "2.3",
"com.google.code.gson" % "gson" % "1.7.1", "com.google.code.gson" % "gson" % "1.7.1",
"redis.clients" % "jedis" % "2.1.0", "redis.clients" % "jedis" % "2.1.0",

View File

@ -16,6 +16,7 @@ public class CreateMeetingRequest implements IBigBlueButtonMessage {
public static class CreateMeetingRequestPayload { public static class CreateMeetingRequestPayload {
public final String id; public final String id;
public final String externalId; public final String externalId;
public final String parentId;
public final String name; public final String name;
public final Boolean record; public final Boolean record;
public final String voiceConfId; public final String voiceConfId;
@ -27,13 +28,17 @@ public class CreateMeetingRequest implements IBigBlueButtonMessage {
public final Long createTime; public final Long createTime;
public final String createDate; public final String createDate;
public final Boolean isBreakout; public final Boolean isBreakout;
public final Integer sequence;
public CreateMeetingRequestPayload(String id, String externalId, String name, Boolean record, String voiceConfId, public CreateMeetingRequestPayload(String id, String externalId,
Integer duration, Boolean autoStartRecording, String parentId, String name, Boolean record,
Boolean allowStartStopRecording, String moderatorPass, String voiceConfId, Integer duration,
String viewerPass, Long createTime, String createDate, Boolean isBreakout) { Boolean autoStartRecording, Boolean allowStartStopRecording,
String moderatorPass, String viewerPass, Long createTime,
String createDate, Boolean isBreakout, Integer sequence) {
this.id = id; this.id = id;
this.externalId = externalId; this.externalId = externalId;
this.parentId = parentId;
this.name = name; this.name = name;
this.record = record; this.record = record;
this.voiceConfId = voiceConfId; this.voiceConfId = voiceConfId;
@ -45,6 +50,7 @@ public class CreateMeetingRequest implements IBigBlueButtonMessage {
this.createTime = createTime; this.createTime = createTime;
this.createDate = createDate; this.createDate = createDate;
this.isBreakout = isBreakout; this.isBreakout = isBreakout;
this.sequence = sequence;
} }
} }
} }

View File

@ -20,14 +20,14 @@ package org.bigbluebutton.messages.payload;
public class BreakoutRoomJoinURLPayload { public class BreakoutRoomJoinURLPayload {
public final String meetingId; public final String parentMeetingId;
public final String breakoutId; public final String breakoutMeetingId;
public final String userId; public final String userId;
public final String joinURL; public final String joinURL;
public BreakoutRoomJoinURLPayload(String meetingId, String breakoutId, String userId, String joinURL) { public BreakoutRoomJoinURLPayload(String parentMeetingId, String breakoutMeetingId, String userId, String joinURL) {
this.meetingId = meetingId; this.parentMeetingId = parentMeetingId;
this.breakoutId = breakoutId; this.breakoutMeetingId = breakoutMeetingId;
this.userId = userId; this.userId = userId;
this.joinURL = joinURL; this.joinURL = joinURL;
} }

View File

@ -2,13 +2,18 @@ package org.bigbluebutton.messages.payload;
public class BreakoutRoomPayload { public class BreakoutRoomPayload {
public final String parentMeetingId;
public final String meetingId; public final String meetingId;
public final String breakoutId; public final String externalMeetingId;
public final String name; public final String name;
public final Integer sequence;
public BreakoutRoomPayload(String meetingId, String breakoutId, String name) { public BreakoutRoomPayload(String parentMeetingId, String meetingId,
String externalMeetingId, String name, Integer sequence) {
this.parentMeetingId = parentMeetingId;
this.meetingId = meetingId; this.meetingId = meetingId;
this.breakoutId = breakoutId; this.externalMeetingId = externalMeetingId;
this.name = name; this.name = name;
this.sequence = sequence;
} }
} }

View File

@ -5,11 +5,14 @@ import java.util.ArrayList;
public class BreakoutRoomRequestPayload { public class BreakoutRoomRequestPayload {
// Name of the breakout room // Name of the breakout room
public final String name; public final String name;
// Sequence of the breakout room
public final Integer sequence;
// List of user ids to assign to the breakout room // List of user ids to assign to the breakout room
public final ArrayList<String> users; public final ArrayList<String> users;
public BreakoutRoomRequestPayload(String name, ArrayList<String> users) { public BreakoutRoomRequestPayload(String name, Integer sequence, ArrayList<String> users) {
this.name = name; this.name = name;
this.sequence = sequence;
this.users = users; this.users = users;
} }
} }

View File

@ -1,27 +1,33 @@
package org.bigbluebutton.messages.payload; package org.bigbluebutton.messages.payload;
public class CreateBreakoutRoomRequestPayload { public class CreateBreakoutRoomRequestPayload {
public final String breakoutId; public final String breakoutMeetingId;
public final String parentId; // The main meeting internal id public final String parentMeetingId; // The main meeting internal id
public final String name; // The name of the breakout room public final String name; // The name of the breakout room
public final Integer sequence; // The sequnce number of the breakout room
public final String voiceConfId; // The voice conference id public final String voiceConfId; // The voice conference id
public final String viewerPassword; public final String viewerPassword;
public final String moderatorPassword; public final String moderatorPassword;
public final Integer durationInMinutes; // The duration of the breakout room public final Integer durationInMinutes; // The duration of the breakout room
public final String defaultPresentationURL; public final String sourcePresentationId;
public final Integer sourcePresentationSlide;
public final Boolean record; public final Boolean record;
public CreateBreakoutRoomRequestPayload(String breakoutId, String parentId, String name, public CreateBreakoutRoomRequestPayload(String meetingMeetingId, String parentMeetingId,
String voiceConfId, String viewerPassword, String moderatorPassword, String name, Integer sequence, String voiceConfId, String viewerPassword,
Integer duration, String defaultPresentationURL, Boolean record) { String moderatorPassword, Integer duration,
this.breakoutId = breakoutId; String sourcePresentationId, Integer sourcePresentationSlide,
this.parentId = parentId; Boolean record) {
this.breakoutMeetingId = meetingMeetingId;
this.parentMeetingId = parentMeetingId;
this.name = name; this.name = name;
this.sequence = sequence;
this.voiceConfId = voiceConfId; this.voiceConfId = voiceConfId;
this.viewerPassword = viewerPassword; this.viewerPassword = viewerPassword;
this.moderatorPassword = moderatorPassword; this.moderatorPassword = moderatorPassword;
this.durationInMinutes = duration; this.durationInMinutes = duration;
this.defaultPresentationURL = defaultPresentationURL; this.sourcePresentationId = sourcePresentationId;
this.sourcePresentationSlide = sourcePresentationSlide;
this.record = record; this.record = record;
} }
} }

View File

@ -11,13 +11,16 @@ public class CreateBreakoutRoomsRequestPayload {
public final Integer durationInMinutes; public final Integer durationInMinutes;
// Breakout rooms recording option // Breakout rooms recording option
public final Boolean record; public final Boolean record;
// Creates join URL with redirect value true or false
public final Boolean redirectOnJoin;
public CreateBreakoutRoomsRequestPayload(String meetingId, public CreateBreakoutRoomsRequestPayload(String meetingId,
ArrayList<BreakoutRoomRequestPayload> breakoutRooms, ArrayList<BreakoutRoomRequestPayload> breakoutRooms,
Integer duration, Boolean record) { Integer duration, Boolean record, Boolean redirectOnJoin) {
this.meetingId = meetingId; this.meetingId = meetingId;
this.rooms = breakoutRooms; this.rooms = breakoutRooms;
this.durationInMinutes = duration; this.durationInMinutes = duration;
this.record = record; this.record = record;
this.redirectOnJoin = redirectOnJoin;
} }
} }

View File

@ -6,10 +6,10 @@ public class ListenInOnBreakoutPayload {
public final String targetMeetingId; public final String targetMeetingId;
public final String userId; public final String userId;
public ListenInOnBreakoutPayload(String meetingId, String breakoutId, public ListenInOnBreakoutPayload(String meetingId, String targetMeetingId,
String userId) { String userId) {
this.meetingId = meetingId; this.meetingId = meetingId;
this.targetMeetingId = breakoutId; this.targetMeetingId = targetMeetingId;
this.userId = userId; this.userId = userId;
} }
} }

View File

@ -3,12 +3,15 @@ package org.bigbluebutton.messages.payload;
public class RequestBreakoutJoinURLPayload { public class RequestBreakoutJoinURLPayload {
public final String meetingId; public final String meetingId;
public final String breakoutId; public final String breakoutMeetingId;
public final String userId; public final String userId;
public final Boolean redirect;
public RequestBreakoutJoinURLPayload(String meetingId, String breakoutId, String userId) { public RequestBreakoutJoinURLPayload(String meetingId,
String breakoutMeetingId, String userId, Boolean redirect) {
this.meetingId = meetingId; this.meetingId = meetingId;
this.breakoutId = breakoutId; this.breakoutMeetingId = breakoutMeetingId;
this.userId = userId; this.userId = userId;
this.redirect = redirect;
} }
} }

View File

@ -5,12 +5,12 @@ import java.util.ArrayList;
public class UpdateBreakoutUsersPayload { public class UpdateBreakoutUsersPayload {
public final ArrayList<BreakoutUserPayload> users; public final ArrayList<BreakoutUserPayload> users;
public final String breakoutId; public final String breakoutMeetingId;
public final String meetingId; public final String parentMeetingId;
public UpdateBreakoutUsersPayload(String meetingId, String breakoutId, ArrayList<BreakoutUserPayload> users) { public UpdateBreakoutUsersPayload(String meetingParentId, String breakoutMeetingId, ArrayList<BreakoutUserPayload> users) {
this.meetingId = meetingId; this.parentMeetingId = meetingParentId;
this.breakoutId = breakoutId; this.breakoutMeetingId = breakoutMeetingId;
this.users = users; this.users = users;
} }
} }

View File

@ -9,19 +9,22 @@ import com.google.gson.Gson;
public class CreateBreakoutRoomRequestTest { public class CreateBreakoutRoomRequestTest {
@Test @Test
public void testCreateBreakoutRoomRequest() { public void testCreateBreakoutRoomRequest() {
String breakoutId = "abc123"; String breakoutId = "183f0bf3a0982a127bdb8161e0c44eb696b3e75c-1474984695664";
String parentId = "abc-123"; String parentId = "abc-123";
Integer durationInMinutes = 20; Integer durationInMinutes = 20;
String name = "Breakout room 1"; String name = "Breakout room 1";
Integer sequence = 3;
String voiceConfId = "851153"; String voiceConfId = "851153";
String viewerPassword = "vp"; String viewerPassword = "vp";
String moderatorPassword = "mp"; String moderatorPassword = "mp";
String defaultPresentationURL = "http://localhost/foo.pdf"; String sourcePresentationId = "d2d9a672040fbde2a47a10bf6c37b6a4b5ae187f-1474984695907";
Integer sourePresentationSlide = 5;
Boolean record = false; Boolean record = false;
CreateBreakoutRoomRequestPayload payload = CreateBreakoutRoomRequestPayload payload = new CreateBreakoutRoomRequestPayload(
new CreateBreakoutRoomRequestPayload(breakoutId, parentId, name, voiceConfId, breakoutId, parentId, name, sequence, voiceConfId,
viewerPassword, moderatorPassword, durationInMinutes, defaultPresentationURL, record); viewerPassword, moderatorPassword, durationInMinutes,
sourcePresentationId, sourePresentationSlide, record);
CreateBreakoutRoomRequest msg = new CreateBreakoutRoomRequest(payload); CreateBreakoutRoomRequest msg = new CreateBreakoutRoomRequest(payload);
Gson gson = new Gson(); Gson gson = new Gson();
String json = gson.toJson(msg); String json = gson.toJson(msg);
@ -30,13 +33,15 @@ public class CreateBreakoutRoomRequestTest {
CreateBreakoutRoomRequest rxMsg = gson.fromJson(json, CreateBreakoutRoomRequest.class); CreateBreakoutRoomRequest rxMsg = gson.fromJson(json, CreateBreakoutRoomRequest.class);
Assert.assertEquals(rxMsg.header.name, CreateBreakoutRoomRequest.NAME); Assert.assertEquals(rxMsg.header.name, CreateBreakoutRoomRequest.NAME);
Assert.assertEquals(rxMsg.payload.breakoutId, breakoutId); Assert.assertEquals(rxMsg.payload.breakoutMeetingId, breakoutId);
Assert.assertEquals(rxMsg.payload.name, name); Assert.assertEquals(rxMsg.payload.name, name);
Assert.assertEquals(rxMsg.payload.sequence, sequence);
Assert.assertEquals(rxMsg.payload.voiceConfId, voiceConfId); Assert.assertEquals(rxMsg.payload.voiceConfId, voiceConfId);
Assert.assertEquals(rxMsg.payload.viewerPassword, viewerPassword); Assert.assertEquals(rxMsg.payload.viewerPassword, viewerPassword);
Assert.assertEquals(rxMsg.payload.moderatorPassword, moderatorPassword); Assert.assertEquals(rxMsg.payload.moderatorPassword, moderatorPassword);
Assert.assertEquals(rxMsg.payload.durationInMinutes, durationInMinutes); Assert.assertEquals(rxMsg.payload.durationInMinutes, durationInMinutes);
Assert.assertEquals(rxMsg.payload.defaultPresentationURL, defaultPresentationURL); Assert.assertEquals(rxMsg.payload.sourcePresentationId, sourcePresentationId);
Assert.assertEquals(rxMsg.payload.sourcePresentationSlide, sourePresentationSlide);
Assert.assertEquals(rxMsg.payload.record, record); Assert.assertEquals(rxMsg.payload.record, record);
} }
} }

View File

@ -15,23 +15,24 @@ public class CreateBreakoutRoomsRequestTest {
String meetingId = "abc123"; String meetingId = "abc123";
Integer durationInMinutes = 20; Integer durationInMinutes = 20;
Boolean record = true; Boolean record = true;
Boolean redirectOnJoin = false;
ArrayList<String> room1Users = new ArrayList<String>(); ArrayList<String> room1Users = new ArrayList<String>();
room1Users.add("Tidora"); room1Users.add("Nidora"); room1Users.add("Tinidora"); room1Users.add("Tidora"); room1Users.add("Nidora"); room1Users.add("Tinidora");
BreakoutRoomRequestPayload room1 = new BreakoutRoomRequestPayload("room1", room1Users); BreakoutRoomRequestPayload room1 = new BreakoutRoomRequestPayload("room1", 1, room1Users);
ArrayList<String> room2Users = new ArrayList<String>(); ArrayList<String> room2Users = new ArrayList<String>();
room2Users.add("Jose"); room2Users.add("Wally"); room2Users.add("Paolo"); room2Users.add("Jose"); room2Users.add("Wally"); room2Users.add("Paolo");
BreakoutRoomRequestPayload room2= new BreakoutRoomRequestPayload("room2", room2Users); BreakoutRoomRequestPayload room2= new BreakoutRoomRequestPayload("room2", 2, room2Users);
ArrayList<String> room3Users = new ArrayList<String>(); ArrayList<String> room3Users = new ArrayList<String>();
room3Users.add("Alden"); room3Users.add("Yaya Dub"); room3Users.add("Alden"); room3Users.add("Yaya Dub");
BreakoutRoomRequestPayload room3= new BreakoutRoomRequestPayload("room3", room3Users); BreakoutRoomRequestPayload room3= new BreakoutRoomRequestPayload("room3", 3, room3Users);
ArrayList<BreakoutRoomRequestPayload> rooms = new ArrayList<BreakoutRoomRequestPayload>(); ArrayList<BreakoutRoomRequestPayload> rooms = new ArrayList<BreakoutRoomRequestPayload>();
rooms.add(room1); rooms.add(room2); rooms.add(room3); rooms.add(room1); rooms.add(room2); rooms.add(room3);
CreateBreakoutRoomsRequestPayload payload = new CreateBreakoutRoomsRequestPayload(meetingId, rooms, durationInMinutes, record); CreateBreakoutRoomsRequestPayload payload = new CreateBreakoutRoomsRequestPayload(meetingId, rooms, durationInMinutes, record, redirectOnJoin);
CreateBreakoutRoomsRequest msg = new CreateBreakoutRoomsRequest(payload); CreateBreakoutRoomsRequest msg = new CreateBreakoutRoomsRequest(payload);
Gson gson = new Gson(); Gson gson = new Gson();
String json = gson.toJson(msg); String json = gson.toJson(msg);

View File

@ -12,6 +12,7 @@ public class CreateMeetingRequestTest {
public void testCreateMeetingRequest() { public void testCreateMeetingRequest() {
String meetingId = "abc123"; String meetingId = "abc123";
String externalId = "extabc123"; String externalId = "extabc123";
String parentId = "";
Boolean record = false; Boolean record = false;
Integer durationInMinutes = 20; Integer durationInMinutes = 20;
String name = "Breakout room 1"; String name = "Breakout room 1";
@ -19,16 +20,17 @@ public class CreateMeetingRequestTest {
Boolean autoStartRecording = false; Boolean autoStartRecording = false;
Boolean allowStartStopRecording = false; Boolean allowStartStopRecording = false;
Boolean isBreakout = true; Boolean isBreakout = true;
Integer sequence = 4;
String viewerPassword = "vp"; String viewerPassword = "vp";
String moderatorPassword = "mp"; String moderatorPassword = "mp";
long createTime = System.currentTimeMillis(); long createTime = System.currentTimeMillis();
String createDate = new Date(createTime).toString(); String createDate = new Date(createTime).toString();
CreateMeetingRequestPayload payload = CreateMeetingRequestPayload payload = new CreateMeetingRequestPayload(
new CreateMeetingRequestPayload(meetingId, externalId, name, record, voiceConfId, meetingId, externalId, parentId, name, record, voiceConfId,
durationInMinutes, autoStartRecording, durationInMinutes, autoStartRecording, allowStartStopRecording,
allowStartStopRecording, moderatorPassword, moderatorPassword, viewerPassword, createTime, createDate,
viewerPassword, createTime, createDate, isBreakout); isBreakout, sequence);
CreateMeetingRequest msg = new CreateMeetingRequest(payload); CreateMeetingRequest msg = new CreateMeetingRequest(payload);
Gson gson = new Gson(); Gson gson = new Gson();
String json = gson.toJson(msg); String json = gson.toJson(msg);
@ -38,11 +40,14 @@ public class CreateMeetingRequestTest {
Assert.assertEquals(rxMsg.header.name, CreateMeetingRequest.NAME); Assert.assertEquals(rxMsg.header.name, CreateMeetingRequest.NAME);
Assert.assertEquals(rxMsg.payload.id, meetingId); Assert.assertEquals(rxMsg.payload.id, meetingId);
Assert.assertEquals(rxMsg.payload.externalId, externalId);
Assert.assertEquals(rxMsg.payload.parentId, parentId);
Assert.assertEquals(rxMsg.payload.name, name); Assert.assertEquals(rxMsg.payload.name, name);
Assert.assertEquals(rxMsg.payload.voiceConfId, voiceConfId); Assert.assertEquals(rxMsg.payload.voiceConfId, voiceConfId);
Assert.assertEquals(rxMsg.payload.viewerPassword, viewerPassword); Assert.assertEquals(rxMsg.payload.viewerPassword, viewerPassword);
Assert.assertEquals(rxMsg.payload.moderatorPassword, moderatorPassword); Assert.assertEquals(rxMsg.payload.moderatorPassword, moderatorPassword);
Assert.assertEquals(rxMsg.payload.durationInMinutes, durationInMinutes); Assert.assertEquals(rxMsg.payload.durationInMinutes, durationInMinutes);
Assert.assertEquals(rxMsg.payload.isBreakout, isBreakout); Assert.assertEquals(rxMsg.payload.isBreakout, isBreakout);
Assert.assertEquals(rxMsg.payload.sequence, sequence);
} }
} }

View File

@ -44,7 +44,7 @@ libraryDependencies ++= {
// "org.pegdown" % "pegdown" % "1.4.0", // "org.pegdown" % "pegdown" % "1.4.0",
// "junit" % "junit" % "4.11", // "junit" % "junit" % "4.11",
// "com.etaty.rediscala" %% "rediscala" % "1.4.0", // "com.etaty.rediscala" %% "rediscala" % "1.4.0",
"commons-codec" % "commons-codec" % "1.8", "commons-codec" % "commons-codec" % "1.10",
"redis.clients" % "jedis" % "2.7.2", "redis.clients" % "jedis" % "2.7.2",
// "org.apache.commons" % "commons-lang3" % "3.2", // "org.apache.commons" % "commons-lang3" % "3.2",
"org.apache.commons" % "commons-pool2" % "2.3", "org.apache.commons" % "commons-pool2" % "2.3",

View File

@ -3,12 +3,11 @@ package org.bigbluebutton.red5.client;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import org.bigbluebutton.common.messages.ChatKeyUtil;
import org.bigbluebutton.common.messages.DeskShareNotifyViewersRTMPEventMessage;
import org.bigbluebutton.common.messages.DeskShareNotifyASingleViewerEventMessage; import org.bigbluebutton.common.messages.DeskShareNotifyASingleViewerEventMessage;
import org.bigbluebutton.common.messages.DeskShareNotifyViewersRTMPEventMessage;
import org.bigbluebutton.red5.client.messaging.BroadcastClientMessage; import org.bigbluebutton.red5.client.messaging.BroadcastClientMessage;
import org.bigbluebutton.red5.client.messaging.DirectClientMessage;
import org.bigbluebutton.red5.client.messaging.ConnectionInvokerService; import org.bigbluebutton.red5.client.messaging.ConnectionInvokerService;
import org.bigbluebutton.red5.client.messaging.DirectClientMessage;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
import com.google.gson.JsonParser; import com.google.gson.JsonParser;

View File

@ -44,7 +44,6 @@ import com.google.gson.Gson;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
import com.google.gson.JsonParser; import com.google.gson.JsonParser;
public class UserClientMessageSender { public class UserClientMessageSender {
private static Logger log = Red5LoggerFactory.getLogger(UserClientMessageSender.class, "bigbluebutton"); private static Logger log = Red5LoggerFactory.getLogger(UserClientMessageSender.class, "bigbluebutton");
@ -543,8 +542,8 @@ public class UserClientMessageSender {
private void processBreakoutRoomJoinURL(BreakoutRoomJoinURL msg) { private void processBreakoutRoomJoinURL(BreakoutRoomJoinURL msg) {
Map<String, Object> args = new HashMap<String, Object>(); Map<String, Object> args = new HashMap<String, Object>();
args.put("meetingId", msg.payload.meetingId); args.put("parentMeetingId", msg.payload.parentMeetingId);
args.put("breakoutId", msg.payload.breakoutId); args.put("breakoutMeetingId", msg.payload.breakoutMeetingId);
args.put("userId", msg.payload.userId); args.put("userId", msg.payload.userId);
args.put("joinURL", msg.payload.joinURL); args.put("joinURL", msg.payload.joinURL);
@ -552,7 +551,7 @@ public class UserClientMessageSender {
Gson gson = new Gson(); Gson gson = new Gson();
message.put("msg", gson.toJson(args)); message.put("msg", gson.toJson(args));
DirectClientMessage m = new DirectClientMessage(msg.payload.meetingId, msg.payload.userId, "breakoutRoomJoinURL", message); DirectClientMessage m = new DirectClientMessage(msg.payload.parentMeetingId, msg.payload.userId, "breakoutRoomJoinURL", message);
service.sendMessage(m); service.sendMessage(m);
} }
@ -584,42 +583,44 @@ public class UserClientMessageSender {
private void processUpdateBreakoutUsers(UpdateBreakoutUsers msg) { private void processUpdateBreakoutUsers(UpdateBreakoutUsers msg) {
Map<String, Object> args = new HashMap<String, Object>(); Map<String, Object> args = new HashMap<String, Object>();
args.put("meetingId", msg.payload.meetingId); args.put("parentMeetingId", msg.payload.parentMeetingId);
args.put("breakoutId", msg.payload.breakoutId); args.put("breakoutMeetingId", msg.payload.breakoutMeetingId);
args.put("users", msg.payload.users); args.put("users", msg.payload.users);
Map<String, Object> message = new HashMap<String, Object>(); Map<String, Object> message = new HashMap<String, Object>();
Gson gson = new Gson(); Gson gson = new Gson();
message.put("msg", gson.toJson(args)); message.put("msg", gson.toJson(args));
BroadcastClientMessage m = new BroadcastClientMessage(msg.payload.meetingId, "updateBreakoutUsers", message); BroadcastClientMessage m = new BroadcastClientMessage(msg.payload.parentMeetingId, "updateBreakoutUsers", message);
service.sendMessage(m); service.sendMessage(m);
} }
private void processBreakoutRoomStarted(BreakoutRoomStarted msg) { private void processBreakoutRoomStarted(BreakoutRoomStarted msg) {
Map<String, Object> args = new HashMap<String, Object>(); Map<String, Object> args = new HashMap<String, Object>();
args.put("breakoutId", msg.payload.breakoutId); args.put("breakoutMeetingId", msg.payload.meetingId);
args.put("meetingId", msg.payload.meetingId); args.put("parentMeetingId", msg.payload.parentMeetingId);
args.put("externalMeetingId", msg.payload.externalMeetingId);
args.put("sequence", msg.payload.sequence);
args.put("name", msg.payload.name); args.put("name", msg.payload.name);
Map<String, Object> message = new HashMap<String, Object>(); Map<String, Object> message = new HashMap<String, Object>();
Gson gson = new Gson(); Gson gson = new Gson();
message.put("msg", gson.toJson(args)); message.put("msg", gson.toJson(args));
BroadcastClientMessage m = new BroadcastClientMessage(msg.payload.meetingId, "breakoutRoomStarted", message); BroadcastClientMessage m = new BroadcastClientMessage(msg.payload.parentMeetingId, "breakoutRoomStarted", message);
service.sendMessage(m); service.sendMessage(m);
} }
private void processBreakoutRoomClosed(BreakoutRoomClosed msg) { private void processBreakoutRoomClosed(BreakoutRoomClosed msg) {
Map<String, Object> args = new HashMap<String, Object>(); Map<String, Object> args = new HashMap<String, Object>();
args.put("breakoutId", msg.payload.breakoutId); args.put("breakoutMeetingId", msg.payload.meetingId);
args.put("meetingId", msg.payload.meetingId); args.put("parentMeetingId", msg.payload.parentMeetingId);
Map<String, Object> message = new HashMap<String, Object>(); Map<String, Object> message = new HashMap<String, Object>();
Gson gson = new Gson(); Gson gson = new Gson();
message.put("msg", gson.toJson(args)); message.put("msg", gson.toJson(args));
BroadcastClientMessage m = new BroadcastClientMessage(msg.payload.meetingId, "breakoutRoomClosed", message); BroadcastClientMessage m = new BroadcastClientMessage(msg.payload.parentMeetingId, "breakoutRoomClosed", message);
service.sendMessage(m); service.sendMessage(m);
} }
} }

View File

@ -1,6 +1,5 @@
package org.bigbluebutton.red5.client; package org.bigbluebutton.red5.client;
import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;

View File

@ -18,9 +18,6 @@
*/ */
package org.bigbluebutton.red5.service; package org.bigbluebutton.red5.service;
import java.util.HashMap;
import java.util.Map;
import org.bigbluebutton.red5.BigBlueButtonSession; import org.bigbluebutton.red5.BigBlueButtonSession;
import org.bigbluebutton.red5.Constants; import org.bigbluebutton.red5.Constants;
import org.bigbluebutton.red5.pubsub.MessagePublisher; import org.bigbluebutton.red5.pubsub.MessagePublisher;

View File

@ -1061,6 +1061,10 @@ EmojiGrid {
horizontalGap: 6; horizontalGap: 6;
} }
.breakoutRoomUserWindowHeadingStyle {
fontWeight: bold;
}
.breakoutRoomSettingTitleStyle { .breakoutRoomSettingTitleStyle {
fontFamily: Arial; fontFamily: Arial;
fontSize: 20; fontSize: 20;

View File

@ -23,8 +23,6 @@
<property name="BROADCAST" value="BroadcastModule" /> <property name="BROADCAST" value="BroadcastModule" />
<property name="CHAT" value="ChatModule" /> <property name="CHAT" value="ChatModule" />
<property name="PRESENT" value="PresentModule" /> <property name="PRESENT" value="PresentModule" />
<property name="DESKSHARE" value="DeskShareModule" />
<property name="DESKSHARE_SA" value="DeskshareStandalone" />
<property name="SCREENSHARE" value="ScreenshareModule" /> <property name="SCREENSHARE" value="ScreenshareModule" />
<property name="SCREENSHARE_SA" value="ScreenshareStandalone" /> <property name="SCREENSHARE_SA" value="ScreenshareStandalone" />
<property name="CAM_PREVIEW_SA" value="WebcamPreviewStandalone" /> <property name="CAM_PREVIEW_SA" value="WebcamPreviewStandalone" />
@ -211,16 +209,6 @@
<build-module src="${SRC_DIR}" target="${PRESENT}" /> <build-module src="${SRC_DIR}" target="${PRESENT}" />
</target> </target>
<target name="build-deskshare-standalone" depends="build-deskshare-no-linker" description="Compile Deskshare Standalone Application">
<echo message="Compiling deskshare standalone without optimization." />
<build-module-no-link src="${SRC_DIR}" target="${DESKSHARE_SA}" />
</target>
<target name="build-deskshare-no-linker" description="Compile Deskshare Module without the linker">
<echo message="Compiling deskshare without optimization." />
<build-module-no-link src="${SRC_DIR}" target="${DESKSHARE}" />
</target>
<target name="build-screenshare-standalone" depends="build-screenshare-no-linker" description="Compile Screenshare Standalone Application"> <target name="build-screenshare-standalone" depends="build-screenshare-no-linker" description="Compile Screenshare Standalone Application">
<echo message="Compiling screenshare standalone without optimization." /> <echo message="Compiling screenshare standalone without optimization." />
<build-module-no-link src="${SRC_DIR}" target="${SCREENSHARE_SA}" /> <build-module-no-link src="${SRC_DIR}" target="${SCREENSHARE_SA}" />
@ -256,13 +244,6 @@
<build-module-no-link src="${SRC_DIR}" target="${CONNECTION_CHECK}" /> <build-module-no-link src="${SRC_DIR}" target="${CONNECTION_CHECK}" />
</target> </target>
<target name="build-deskshare" description="Compile Deskshare Module">
<build-module src="${SRC_DIR}" target="${DESKSHARE}" />
<echo message="Copying deskshare applet for Deskshare Module" />
<copy file="${PROD_RESOURCES_DIR}/bbb-deskshare-applet-unsigned-0.9.0.jar" todir="${OUTPUT_DIR}"/>
<copy file="${PROD_RESOURCES_DIR}/bbb-deskshare-applet-0.9.0.jar" todir="${OUTPUT_DIR}"/>
</target>
<target name="build-screenshare" description="Compile Screenshare Module"> <target name="build-screenshare" description="Compile Screenshare Module">
<build-module src="${SRC_DIR}" target="${SCREENSHARE}" /> <build-module src="${SRC_DIR}" target="${SCREENSHARE}" />
<echo message="Copying deskshare applet for Screenshare Module" /> <echo message="Copying deskshare applet for Screenshare Module" />
@ -304,9 +285,9 @@
</target> </target>
<!-- just a grouping of modules to compile --> <!-- just a grouping of modules to compile -->
<target name="build-deskshare-phone-video-whiteboard-dyn" <target name="build-screenshare-phone-video-whiteboard-dyn"
depends="build-deskshare, build-screenshare, build-phone, build-video, build-whiteboard, build-notes, build-polling" depends="build-screenshare, build-phone, build-video, build-whiteboard, build-notes, build-polling"
description="Compile deskshare, phone, video, whiteboard modules"> description="Compile screenshare, phone, video, whiteboard modules">
</target> </target>
<macrodef name="build-main"> <macrodef name="build-main">
@ -402,17 +383,12 @@
</sequential> </sequential>
</macrodef> </macrodef>
<target name="compile-deskshare-standalone" depends="build-deskshare-standalone"
description="Compiling standalone desktop sharing">
<echo message="Deskshare standalone built without optimization." />
</target>
<target name="compile-screenshare-standalone" depends="build-screenshare-standalone" <target name="compile-screenshare-standalone" depends="build-screenshare-standalone"
description="Compiling standalone screen sharing"> description="Compiling standalone screen sharing">
<echo message="Screenshare standalone built without optimization." /> <echo message="Screenshare standalone built without optimization." />
</target> </target>
<target name="compile-bbb" depends="build-main-chat-present, build-deskshare-phone-video-whiteboard-dyn, copy-resource-files" <target name="compile-bbb" depends="build-main-chat-present, build-screenshare-phone-video-whiteboard-dyn, copy-resource-files"
description="Compiling the BBB without copying config.xml"> description="Compiling the BBB without copying config.xml">
</target> </target>
@ -446,7 +422,7 @@
</copy> </copy>
<copy file="${PROD_RESOURCES_DIR}/BigBlueButtonTest.html" todir="${OUTPUT_DIR}" overwrite="true"/> <copy file="${PROD_RESOURCES_DIR}/BigBlueButtonTest.html" todir="${OUTPUT_DIR}" overwrite="true"/>
<copy file="${PROD_RESOURCES_DIR}/BigBlueButton.html" todir="${OUTPUT_DIR}" overwrite="true"/> <copy file="${PROD_RESOURCES_DIR}/BigBlueButton.html" todir="${OUTPUT_DIR}" overwrite="true"/>
<copy file="${PROD_RESOURCES_DIR}/DeskshareStandalone.html" todir="${OUTPUT_DIR}" overwrite="true"/> <copy file="${PROD_RESOURCES_DIR}/ScreenshareStandalone.html" todir="${OUTPUT_DIR}" overwrite="true"/>
<copy file="${PROD_RESOURCES_DIR}/get_flash_player.gif" todir="${OUTPUT_DIR}" overwrite="true"/> <copy file="${PROD_RESOURCES_DIR}/get_flash_player.gif" todir="${OUTPUT_DIR}" overwrite="true"/>
<copy file="${PROD_RESOURCES_DIR}/bbb.gif" todir="${OUTPUT_DIR}" overwrite="true"/> <copy file="${PROD_RESOURCES_DIR}/bbb.gif" todir="${OUTPUT_DIR}" overwrite="true"/>
<copy file="${PROD_RESOURCES_DIR}/avatar.png" todir="${OUTPUT_DIR}" overwrite="true"/> <copy file="${PROD_RESOURCES_DIR}/avatar.png" todir="${OUTPUT_DIR}" overwrite="true"/>
@ -534,19 +510,17 @@
</if> </if>
</target> </target>
<!-- NOTE: compile-deskshare-standalone MUST come first before compile-bbb as we need the deskshare-standalone <!-- NOTE: compile-screenshare-standalone MUST come first before compile-bbb as we need the screenshare-standalone
to be compiled withouth being optimized by using the linker --> to be compiled without being optimized by using the linker -->
<target name="clean-build-bbb" depends="clean, init-ant-contrib, generate-html-wrapper, compile-deskshare-standalone, <target name="clean-build-bbb" depends="clean, init-ant-contrib, generate-html-wrapper, compile-screenshare-standalone,
compile-screenshare-standalone,
build-webcam-preview-standalone, build-webcam-view-standalone, compile-bbb" build-webcam-preview-standalone, build-webcam-view-standalone, compile-bbb"
description="Build BBB client skipping compiling of locales"/> description="Build BBB client skipping compiling of locales"/>
<target name="clean-build-all" depends="clean, init-ant-contrib, generate-html-wrapper, compile-deskshare-standalone, <target name="clean-build-all" depends="clean, init-ant-contrib, generate-html-wrapper,
compile-screenshare-standalone, build-mic-check, compile-screenshare-standalone, build-mic-check,
build-cam-check, build-conn-check, build-webcam-preview-standalone, build-webcam-view-standalone, build-cam-check, build-conn-check, build-webcam-preview-standalone, build-webcam-view-standalone,
compile-bbb, branding, branding-black" compile-bbb, branding, branding-black"
description="Build BBB client including locales"/> description="Build BBB client including locales"/>
<target name="modules" depends="init-ant-contrib, generate-html-wrapper, compile-deskshare-standalone, <target name="modules" depends="init-ant-contrib, generate-html-wrapper, compile-screenshare-standalone,
compile-screenshare-standalone,
build-webcam-preview-standalone, build-webcam-view-standalone, compile-bbb" build-webcam-preview-standalone, build-webcam-view-standalone, compile-bbb"
description="Build BBB client without locales"/> description="Build BBB client without locales"/>
<target name="cleanandmake" depends="clean-build-all" description="Build BBB client including locales"/> <target name="cleanandmake" depends="clean-build-all" description="Build BBB client including locales"/>

View File

@ -114,10 +114,6 @@ bbb.clientstatus.flash.title = Flash Player
bbb.clientstatus.flash.message = Your Flash Player plugin ({0}) is out-of-date. Recommend updating to the latest version. bbb.clientstatus.flash.message = Your Flash Player plugin ({0}) is out-of-date. Recommend updating to the latest version.
bbb.clientstatus.webrtc.title = Audio bbb.clientstatus.webrtc.title = Audio
bbb.clientstatus.webrtc.message = Recommend using either Firefox or Chrome for better audio. bbb.clientstatus.webrtc.message = Recommend using either Firefox or Chrome for better audio.
bbb.clientstatus.java.title = Java
bbb.clientstatus.java.notdetected = Java version not detected.
bbb.clientstatus.java.notinstalled = You have no Java installed, please click <font color='#0a4a7a'><a href='http://www.java.com/download/' target='_blank'>HERE</a></font> to install the latest Java to use the desktop sharing feature.
bbb.clientstatus.java.oldversion = You have an old Java installed, please click <font color='#0a4a7a'><a href='http://www.java.com/download/' target='_blank'>HERE</a></font> to install the latest Java to use the desktop sharing feature.
bbb.window.minimizeBtn.toolTip = Minimize bbb.window.minimizeBtn.toolTip = Minimize
bbb.window.maximizeRestoreBtn.toolTip = Maximize bbb.window.maximizeRestoreBtn.toolTip = Maximize
bbb.window.closeBtn.toolTip = Close bbb.window.closeBtn.toolTip = Close
@ -287,17 +283,16 @@ bbb.video.publish.closeBtn.accessName = Close the webcam settings dialog box
bbb.video.publish.closeBtn.label = Cancel bbb.video.publish.closeBtn.label = Cancel
bbb.video.publish.titleBar = Publish Webcam Window bbb.video.publish.titleBar = Publish Webcam Window
bbb.video.streamClose.toolTip = Close stream for: {0} bbb.video.streamClose.toolTip = Close stream for: {0}
bbb.screensharePublish.title = Desktop Sharing: Presenter's Preview bbb.screensharePublish.title = Screen Sharing: Presenter's Preview
bbb.screensharePublish.pause.tooltip = Pause screen share bbb.screensharePublish.pause.tooltip = Pause screen share
bbb.screensharePublish.pause.label = Pause bbb.screensharePublish.pause.label = Pause
bbb.screensharePublish.restart.tooltip = Restart screen share bbb.screensharePublish.restart.tooltip = Restart screen share
bbb.screensharePublish.restart.label = Restart bbb.screensharePublish.restart.label = Restart
bbb.screensharePublish.maximizeRestoreBtn.toolTip = You cannot maximize this window. bbb.screensharePublish.maximizeRestoreBtn.toolTip = You cannot maximize this window.
bbb.screensharePublish.closeBtn.toolTip = Stop Sharing and Close bbb.screensharePublish.closeBtn.toolTip = Stop Sharing and Close
bbb.screensharePublish.chromeOnMacUnsupportedHint = Desktop sharing is not currently supported on Chrome running under Mac OS X. Recommend you use FireFox to share desktop.
bbb.screensharePublish.minimizeBtn.toolTip = Minimize bbb.screensharePublish.minimizeBtn.toolTip = Minimize
bbb.screensharePublish.minimizeBtn.accessibilityName = Minimize the Desktop Sharing Publish Window bbb.screensharePublish.minimizeBtn.accessibilityName = Minimize the Screen Sharing Publish Window
bbb.screensharePublish.maximizeRestoreBtn.accessibilityName = Maximize the Desktop Sharing Publish Window bbb.screensharePublish.maximizeRestoreBtn.accessibilityName = Maximize the Screen Sharing Publish Window
bbb.screensharePublish.commonHelpText.text = The steps below will guide you through starting screen sharing (requires Java). bbb.screensharePublish.commonHelpText.text = The steps below will guide you through starting screen sharing (requires Java).
bbb.screensharePublish.helpButton.toolTip = Help bbb.screensharePublish.helpButton.toolTip = Help
bbb.screensharePublish.helpButton.accessibilityName = Help (Opens tutorial in a new window) bbb.screensharePublish.helpButton.accessibilityName = Help (Opens tutorial in a new window)
@ -331,7 +326,7 @@ bbb.screensharePublish.helpText.LinuxChrome3 = 3. Accept the certificate
bbb.screensharePublish.shareTypeLabel.text = Share: bbb.screensharePublish.shareTypeLabel.text = Share:
bbb.screensharePublish.shareType.fullScreen = Full screen bbb.screensharePublish.shareType.fullScreen = Full screen
bbb.screensharePublish.shareType.region = Region bbb.screensharePublish.shareType.region = Region
bbb.screensharePublish.pauseMessage.label = Desktop sharing is currently paused. bbb.screensharePublish.pauseMessage.label = Screen sharing is currently paused.
bbb.screensharePublish.startFailed.label = Did not detect start of screen sharing. bbb.screensharePublish.startFailed.label = Did not detect start of screen sharing.
bbb.screensharePublish.restartFailed.label = Did not detect restart of screen sharing. bbb.screensharePublish.restartFailed.label = Did not detect restart of screen sharing.
bbb.screensharePublish.jwsCrashed.label = The screen sharing application closed unexpectedly. bbb.screensharePublish.jwsCrashed.label = The screen sharing application closed unexpectedly.
@ -339,43 +334,19 @@ bbb.screensharePublish.commonErrorMessage.label = Select 'Cancel' and try again.
bbb.screensharePublish.cancelButton.label = Cancel bbb.screensharePublish.cancelButton.label = Cancel
bbb.screensharePublish.startButton.label = Start bbb.screensharePublish.startButton.label = Start
bbb.screensharePublish.stopButton.label = Stop bbb.screensharePublish.stopButton.label = Stop
bbb.screenshareView.title = Desktop Sharing bbb.screenshareView.title = Screen Sharing
bbb.screenshareView.fitToWindow = Fit to Window bbb.screenshareView.fitToWindow = Fit to Window
bbb.screenshareView.actualSize = Display actual size bbb.screenshareView.actualSize = Display actual size
bbb.screenshareView.minimizeBtn.accessibilityName = Minimize the Desktop Sharing View Window bbb.screenshareView.minimizeBtn.accessibilityName = Minimize the Screen Sharing View Window
bbb.screenshareView.maximizeRestoreBtn.accessibilityName = Maximize the Desktop Sharing View Window bbb.screenshareView.maximizeRestoreBtn.accessibilityName = Maximize the Screen Sharing View Window
bbb.screenshareView.closeBtn.accessibilityName = Close the Desktop Sharing View Window bbb.screenshareView.closeBtn.accessibilityName = Close the Screen Sharing View Window
bbb.desktopPublish.title = Desktop Sharing: Presenter's Preview
bbb.desktopPublish.fullscreen.tooltip = Share Your Main Screen
bbb.desktopPublish.fullscreen.label = Full Screen
bbb.desktopPublish.region.tooltip = Share a Part of Your Screen
bbb.desktopPublish.region.label = Region
bbb.desktopPublish.stop.tooltip = Close screen share
bbb.desktopPublish.stop.label = Close
bbb.desktopPublish.maximizeRestoreBtn.toolTip = You cannot maximize this window.
bbb.desktopPublish.closeBtn.toolTip = Stop Sharing and Close
bbb.desktopPublish.chromeOnMacUnsupportedHint = Desktop sharing is not currently supported on Chrome running under Mac OS X. You must use a different web browser (Firefox recommended) to share your desktop.
bbb.desktopPublish.chrome42UnsupportedHint = Chrome no longer supports Java Applets. You must use a different web browser (Firefox recommended) to share your desktop.
bbb.desktopPublish.edgePluginUnsupportedHint = Edge does not support Java Applets. You must use a different web browser (Firefox recommended) to share your desktop.
bbb.desktopPublish.minimizeBtn.toolTip = Minimize
bbb.desktopPublish.minimizeBtn.accessibilityName = Minimize the Desktop Sharing Publish Window
bbb.desktopPublish.maximizeRestoreBtn.accessibilityName = Maximize the Desktop Sharing Publish Window
bbb.desktopPublish.chromeHint.title = Chrome may need your permission.
bbb.desktopPublish.chromeHint.message = Select the plug-in icon (upper right-hand corner of Chrome), un-block plug-ins, and then select 'Retry'.
bbb.desktopPublish.chromeHint.button = Retry
bbb.desktopView.title = Desktop Sharing
bbb.desktopView.fitToWindow = Fit to Window
bbb.desktopView.actualSize = Display actual size
bbb.desktopView.minimizeBtn.accessibilityName = Minimize the Desktop Sharing View Window
bbb.desktopView.maximizeRestoreBtn.accessibilityName = Maximize the Desktop Sharing View Window
bbb.desktopView.closeBtn.accessibilityName = Close the Desktop Sharing View Window
bbb.toolbar.phone.toolTip.start = Share Your Microphone bbb.toolbar.phone.toolTip.start = Share Your Microphone
bbb.toolbar.phone.toolTip.stop = Stop Sharing Your Microphone bbb.toolbar.phone.toolTip.stop = Stop Sharing Your Microphone
bbb.toolbar.phone.toolTip.mute = Stop listening the conference bbb.toolbar.phone.toolTip.mute = Stop listening the conference
bbb.toolbar.phone.toolTip.unmute = Start listening the conference bbb.toolbar.phone.toolTip.unmute = Start listening the conference
bbb.toolbar.phone.toolTip.nomic = No microphone detected bbb.toolbar.phone.toolTip.nomic = No microphone detected
bbb.toolbar.deskshare.toolTip.start = Share Your Desktop bbb.toolbar.deskshare.toolTip.start = Share Your Screen
bbb.toolbar.deskshare.toolTip.stop = Stop Sharing Your Desktop bbb.toolbar.deskshare.toolTip.stop = Stop Sharing Your Screen
bbb.toolbar.video.toolTip.start = Share Your Webcam bbb.toolbar.video.toolTip.start = Share Your Webcam
bbb.toolbar.video.toolTip.stop = Stop Sharing Your Webcam bbb.toolbar.video.toolTip.stop = Stop Sharing Your Webcam
bbb.layout.addButton.toolTip = Add the custom layout to the list bbb.layout.addButton.toolTip = Add the custom layout to the list
@ -446,9 +417,6 @@ bbb.notes.saveBtn.toolTip = Save Note
bbb.settings.deskshare.instructions = Choose Allow on the prompt that pops up to check that desktop sharing is working properly for you bbb.settings.deskshare.instructions = Choose Allow on the prompt that pops up to check that desktop sharing is working properly for you
bbb.settings.deskshare.start = Check Desktop Sharing bbb.settings.deskshare.start = Check Desktop Sharing
bbb.settings.voice.volume = Microphone Activity bbb.settings.voice.volume = Microphone Activity
bbb.settings.java.label = Java version error
bbb.settings.java.text = You have Java {0} installed, but you need at least version {1} to use the BigBlueButton desktop sharing feature. The button below will install the newest Java JRE version.
bbb.settings.java.command = Install newest Java
bbb.settings.flash.label = Flash version error bbb.settings.flash.label = Flash version error
bbb.settings.flash.text = You have Flash {0} installed, but you need at least version {1} to run BigBlueButton properly. The button below will install the newest Adobe Flash version. bbb.settings.flash.text = You have Flash {0} installed, but you need at least version {1} to run BigBlueButton properly. The button below will install the newest Adobe Flash version.
bbb.settings.flash.command = Install newest Flash bbb.settings.flash.command = Install newest Flash
@ -677,11 +645,14 @@ bbb.users.breakout.remainingTimeParent = <b>{1} remaining</b>
bbb.users.breakout.calculatingRemainingTime = Calculating remaining time... bbb.users.breakout.calculatingRemainingTime = Calculating remaining time...
bbb.users.breakout.remainingTimeEnded = Time ended, breakout room will close. bbb.users.breakout.remainingTimeEnded = Time ended, breakout room will close.
bbb.users.breakout.rooms = Rooms bbb.users.breakout.rooms = Rooms
bbb.users.breakout.roomsCombo.accessibilityName = Number of rooms to create
bbb.users.breakout.room = Room bbb.users.breakout.room = Room
bbb.users.breakout.randomAssign = Randomly Assign Users bbb.users.breakout.randomAssign = Randomly Assign Users
bbb.users.breakout.timeLimit = Time Limit bbb.users.breakout.timeLimit = Time Limit
bbb.users.breakout.durationStepper.accessibilityName = Time limit in minutes
bbb.users.breakout.minutes = Minutes bbb.users.breakout.minutes = Minutes
bbb.users.breakout.record = Record bbb.users.breakout.record = Record
bbb.users.breakout.recordCheckbox.accessibilityName = Record breakout rooms
bbb.users.breakout.notAssigned = Not Assigned bbb.users.breakout.notAssigned = Not Assigned
bbb.users.breakout.dragAndDropToolTip = Tip: You can drag and drop users between rooms bbb.users.breakout.dragAndDropToolTip = Tip: You can drag and drop users between rooms
bbb.users.breakout.start = Start bbb.users.breakout.start = Start

View File

@ -24,7 +24,6 @@
</style> </style>
<script type="text/javascript" src="swfobject/swfobject.js"></script> <script type="text/javascript" src="swfobject/swfobject.js"></script>
<script src="lib/deployJava.js?v=VERSION" language="javascript"></script>
<script type="text/javascript"> <script type="text/javascript">
// Check for Firefox 41.0.1/2 to workaround Flash hang // Check for Firefox 41.0.1/2 to workaround Flash hang
// See https://bugzilla.mozilla.org/show_bug.cgi?id=1210665 // See https://bugzilla.mozilla.org/show_bug.cgi?id=1210665
@ -106,7 +105,6 @@
<script src="lib/Screen-Capturing.js" language="javascript"></script> <script src="lib/Screen-Capturing.js" language="javascript"></script>
<script src="lib/verto_extension.js" language="javascript"></script> <script src="lib/verto_extension.js" language="javascript"></script>
<script src="lib/bbb_deskshare.js?v=VERSION" language="javascript"></script>
<script src="lib/bbb_api_bridge.js?v=VERSION" language="javascript"></script> <script src="lib/bbb_api_bridge.js?v=VERSION" language="javascript"></script>
<script src="lib/sip.js?v=VERSION" language="javascript"></script> <script src="lib/sip.js?v=VERSION" language="javascript"></script>
<script src="lib/bbb_webrtc_bridge_sip.js?v=VERSION" language="javascript"></script> <script src="lib/bbb_webrtc_bridge_sip.js?v=VERSION" language="javascript"></script>

View File

@ -1,57 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<style type="text/css" media="screen">
html, body, #content { height:100%; }
body { margin:0; padding:0; overflow:hidden; }
#altContent { /* style alt content */ }
</style>
<script type="text/javascript" src="swfobject/swfobject.js"></script>
<script type="text/javascript">
swfobject.registerObject("BigBlueButton", "10.3.0", "expressInstall.swf");
</script>
<script src="lib/jquery-2.1.1.min.js" language="javascript"></script>
<!--<script src="lib/jquery-1.5.1.min.js" language="javascript"></script>-->
<script src="lib/bigbluebutton.js" language="javascript"></script>
<script src="lib/bbb_localization.js" language="javascript"></script>
<script src="lib/bbb_blinker.js" language="javascript"></script>
<script src="lib/jquery.mobile.min.js" language="javascript"></script>
<script src="lib/jquery.json-2.4.min.js" language="javascript"></script>
<script src="lib/jquery.cookie.js" language="javascript"></script>
<script src="lib/jquery.dataTables.min.js" language="javascript"></script>
<script src="lib/getScreenId.js" language="javascript"></script>
<script src="lib/jquery.FSRTC.js" language="javascript"></script>
<script src="lib/jquery.jsonrpcclient.js" language="javascript"></script>
<script src="lib/jquery.verto.js" language="javascript"></script>
<script src="lib/Screen-Capturing.js" language="javascript"></script>
<script src="lib/verto_extension.js" language="javascript"></script>
<script src="lib/verto_extension_share.js" language="javascript"></script>
<script src="lib/bbb_deskshare.js" language="javascript"></script>
</head>
<body>
<div id="content">
<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="100%" height="100%" id="BigBlueButton" name="BigBlueButton" align="middle">
<param name="movie" value="DeskshareStandalone.swf?v=VERSION" />
<param name="quality" value="high" />
<param name="allowfullscreen" value="true" />
<param name="bgcolor" value="#869ca7" />
<!--[if !IE]>-->
<object type="application/x-shockwave-flash" data="DeskshareStandalone.swf?v=VERSION" width="100%" height="100%" align="middle">
<param name="quality" value="high" />
<param name="bgcolor" value="#869ca7" />
<!--<![endif]-->
<a href="http://www.adobe.com/go/getflashplayer">
<img src="//www.adobe.com/images/shared/download_buttons/get_flash_player.gif" alt="Get Adobe Flash player" />
</a>
<!--[if !IE]>-->
</object>
<!--<![endif]-->
</object>
</div>
</body>
</html>

View File

@ -16,7 +16,7 @@
<script src="lib/bigbluebutton.js" language="javascript"></script> <script src="lib/bigbluebutton.js" language="javascript"></script>
<script src="lib/bbb_localization.js" language="javascript"></script> <script src="lib/bbb_localization.js" language="javascript"></script>
<script src="lib/bbb_blinker.js" language="javascript"></script> <script src="lib/bbb_blinker.js" language="javascript"></script>
<script src="lib/bbb_deskshare.js" language="javascript"></script> <script src="lib/bbb_screenshare.js" language="javascript"></script>
</head> </head>
<body> <body>
<div id="controls"/> <div id="controls"/>

View File

@ -505,13 +505,6 @@
} }
} }
BBB.javaAppletLaunched = function() {
var swfObj = getSwfObj();
if (swfObj) {
swfObj.javaAppletLaunched();
}
}
// Third-party JS apps should use this to query if the BBB SWF file is ready to handle calls. // Third-party JS apps should use this to query if the BBB SWF file is ready to handle calls.
BBB.isSwfClientReady = function() { BBB.isSwfClientReady = function() {
return swfReady; return swfReady;

View File

@ -1,174 +0,0 @@
if (!window.console) window.console = {};
if (!window.console.log) window.console.log = function () { };
function startApplet(IP, useTLS , roomNumber, fullScreen, useSVC2)
{
var deskshareElement = document.getElementById("deskshare");
if (deskshareElement == null) {
console.log("Starting deskshare applet.");
var div = document.createElement("div");
div.id = "deskshare";
div.innerHTML =
"<applet code=\"org.bigbluebutton.deskshare.client.DeskShareApplet.class\"" +
"id=\"DeskShareApplet\" width=\"100\" height=\"10\" archive=\"bbb-deskshare-applet-0.9.0.jar\">" +
"<param name=\"ROOM\" value=\"" + roomNumber + "\"/>" +
"<param name=\"IP\" value=\"" + IP + "\"/>" +
"<param name=\"useTLS\" value=\"" + useTLS + "\"/>" +
"<param name=\"PORT\" value=\"9123\"/>" +
"<param name=\"SCALE\" value=\"0.8\"/>" +
"<param name=\"FULL_SCREEN\" value=\"" + fullScreen + "\"/>" +
"<param name=\"SVC2\" value=\"" + useSVC2 + "\"/>" +
"<param name=\"JavaVersion\" value=\"1.7.0_51\"/>" +
"<param name=\"permissions\" value=\"all-permissions\"/>" +
"</applet>";
document.body.appendChild(div);
} else {
console.log("Deskshare applet element already exists.");
var div = document.getElementById("deskshare");
if (div.parentNode) {
// Just rewrite the applet tag to kick off the applet. We don't remove the applet tag
// when desktop sharing is stopped to prevent Firefox (38.0.5) from asking for user permissions
// again resulting in the page reloading. (ralam june 17, 2015)
// https://code.google.com/p/bigbluebutton/issues/detail?id=1953
div.innerHTML =
"<applet code=\"org.bigbluebutton.deskshare.client.DeskShareApplet.class\"" +
"id=\"DeskShareApplet\" width=\"100\" height=\"10\" archive=\"bbb-deskshare-applet-0.9.0.jar\">" +
"<param name=\"ROOM\" value=\"" + roomNumber + "\"/>" +
"<param name=\"IP\" value=\"" + IP + "\"/>" +
"<param name=\"PORT\" value=\"9123\"/>" +
"<param name=\"SCALE\" value=\"0.8\"/>" +
"<param name=\"FULL_SCREEN\" value=\"" + fullScreen + "\"/>" +
"<param name=\"SVC2\" value=\"" + useSVC2 + "\"/>" +
"<param name=\"JavaVersion\" value=\"1.7.0_51\"/>" +
"<param name=\"permissions\" value=\"all-permissions\"/>" +
"</applet>";
}
}
}
function removeFrame () {
var div = document.getElementById("deskshare");
if (div.parentNode) {
// Need to set the innerHTML otherwise the applet will restart in IE.
// see https://code.google.com/p/bigbluebutton/issues/detail?id=1776
// Do NOT remove the applet tag as it makes Firefox (38.0.5) prompt for
// permissions again resulting in the page reloading. (ralam june 17, 2015)
// div.innerHTML = "";
// div.parentNode.removeChild(div);
}
}
function setScreenCoordinates(x, y) {
document.DeskShareApplet.setScreenCoordinates(x,y);
}
function stopApplet(){
console.log("Stopping deskshare applet.");
removeFrame();
}
function appletStartupCallback() {
BBB.javaAppletLaunched();
}
function getHighestJavaVersion(javas) {
var highestJava = javas[0];
console.log("highestJava = [" + highestJava + "]");
for (j = 0; j < javas.length; j++) {
var java = javas[j];
console.log("java[" + j + "]=[" + java + "]");
var highest = highestJava.split(".");
console.log(highest);
var iter = java.split(".");
console.log(iter);
if (parseInt(iter[0]) > parseInt(highest[0])) {
highestJava = java;
} else if (parseInt(iter[0]) == parseInt(highest[0]) && parseInt(iter[1]) > parseInt(highest[1])) {
highestJava = java;
console.log(highestJava);
} else if (parseInt(iter[0]) == parseInt(highest[0]) && parseInt(iter[1]) == parseInt(highest[1])) {
var iterMinor = parseInt((iter[2]).split("_")[1]);
var highestMinor = parseInt((highest[2]).split("_")[1]);
if (iterMinor > highestMinor) {
highestJava = java;
console.log(highestJava);
}
}
}
return highestJava;
}
function getIcedTeaWebVersion() {
for (i = 0; i < navigator.plugins.length; i++) {
var matches;
if (matches = navigator.plugins[i].name.match(/using IcedTea-Web ([0-9.]+)/)) {
return matches[1];
}
}
return null;
}
function isJavaVersionOk(installedVersion, minVersion) {
var required = minVersion.split(".");
highest = installedVersion.split(".");
if (parseInt(required[0]) > parseInt(highest[0])) {
console.log("older major version=[" + installedVersion + "]");
return {result: "JAVA_OLDER", version: installedVersion};
} else if (parseInt(required[0]) == parseInt(highest[0]) && parseInt(required[1]) > parseInt(highest[1])) {
console.log("older minor version=[" + installedVersion + "]");
return {result: "JAVA_OLDER", version: installedVersion};
} else if (parseInt(required[0]) == parseInt(highest[0]) && parseInt(required[1]) == parseInt(highest[1])) {
var requiredMinor = parseInt((required[2]).split("_")[1]);
var highestJavaMinor = parseInt((highest[2]).split("_")[1]);
if (requiredMinor > highestJavaMinor) {
console.log("older update version=[" + installedVersion + "]");
return {result: "JAVA_OLDER", version: installedVersion};
}
}
return {result: "JAVA_OK"};
}
function isIcedTeaVersionOkLinux(installedVersion, minVersion) {
var required = minVersion.split(".");
highest = installedVersion.split(".");
if (parseInt(required[0]) > parseInt(highest[0])) {
console.log("ice: older major version=[" + installedVersion + "]");
return {result: "JAVA_OLDER", version: installedVersion};
} else if (parseInt(required[0]) == parseInt(highest[0]) && parseInt(required[1]) > parseInt(highest[1])) {
console.log("ice: older minor version=[" + installedVersion + "]");
return {result: "JAVA_OLDER", version: installedVersion};
}
return {result: "JAVA_OK"};
}
function checkJavaVersion(minJavaVersion) {
var javas = deployJava.getJREs();
var highestJavaVersion = null;
if (javas == null || javas.length == 0) {
if (javas == null) {
return {result:"JAVA_NOT_DETECTED"};
}
if (javas.length == 0) {
return {result: "JAVA_NOT_INSTALLED"};
}
} else {
var highestJavaVersion = getHighestJavaVersion(javas);
var isOk = isJavaVersionOk(highestJavaVersion, minJavaVersion);
if (isOk.result === "JAVA_OLDER") {
highestJavaVersion = getIcedTeaWebVersion();
return isIcedTeaVersionOkLinux(highestJavaVersion, "1.5.0");
} else {
return isOk;
}
}
}

File diff suppressed because one or more lines are too long

View File

@ -1,113 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
This program is free software; you can redistribute it and/or modify it under the
terms of the GNU Lesser General Public License as published by the Free Software
Foundation; either version 3.0 of the License, or (at your option) any later
version.
BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
-->
<mx:Module xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:maps="org.bigbluebutton.modules.deskshare.maps.*"
implements="org.bigbluebutton.common.IBigBlueButtonModule"
creationComplete="onCreationComplete()">
<maps:DeskshareEventMap id="javaDeskshareEventMap" />
<maps:WebRTCDeskshareEventMap id="webRTCDeskshareEventMap" />
<mx:Script>
<![CDATA[
import com.asfusion.mate.events.Dispatcher;
import org.as3commons.logging.api.ILogger;
import org.as3commons.logging.api.getClassLogger;
import org.bigbluebutton.common.IBigBlueButtonModule;
import org.bigbluebutton.modules.deskshare.events.ModuleEvent;
private static const LOGGER:ILogger = getClassLogger(DeskShareModule);
private var _moduleName:String = "Desk Share";
private var _attributes:Object;
private var globalDispatcher:Dispatcher = new Dispatcher();;
private function onCreationComplete():void{
LOGGER.debug("DeskShareModule initialized");
}
public function get moduleName():String{
return _moduleName;
}
public function get uri():String{
return _attributes.uri;
}
public function get username():String{
return _attributes.username;
}
public function get mode():String{
if (_attributes.mode == null){
_attributes.mode = "LIVE";
LOGGER.debug("Setting DeskShare mode: {0}", [_attributes.mode]);
}
LOGGER.debug("DeskShare mode: {0}", [_attributes.mode]);
return _attributes.mode;
}
public function get userid():Number{
return _attributes.userid as Number;
}
public function get role():String{
return _attributes.userrole as String;
}
public function start(attributes:Object):void{
LOGGER.debug("desk share attr: {0}", [attributes.username]);
_attributes = attributes;
var startEvent:ModuleEvent = new ModuleEvent(ModuleEvent.START);
startEvent.module = this;
globalDispatcher.dispatchEvent(startEvent);
}
public function stop():void{
LOGGER.debug("STOPPING DESKSHARE MODULE!!!");
var stopEvent:ModuleEvent = new ModuleEvent(ModuleEvent.STOP);
globalDispatcher.dispatchEvent(stopEvent);
}
public function getRoom():String{
return _attributes.room;
}
public function getRed5ServerUri():String{
return _attributes.uri;
}
public function tunnel():Boolean {
if (_attributes.protocol == "RTMPT") {
LOGGER.debug("Use tunneling for desktop sharing");
return true;
}
return false;
}
]]>
</mx:Script>
</mx:Module>

View File

@ -1,355 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
This program is free software; you can redistribute it and/or modify it under the
terms of the GNU Lesser General Public License as published by the Free Software
Foundation; either version 3.0 of the License, or (at your option) any later
version.
BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
-->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:mate="http://mate.asfusion.com/"
creationComplete="onCreationComplete()" resize="onResize()"
backgroundColor="white"
width="100%" height="100%"
layout="absolute">
<mate:Listener type="{AppletStartedEvent.APPLET_STARTED}" method="onAppletStart" />
<mate:Listener type="{ViewStreamEvent.STOP}" method="onAppletStop" />
<mate:Listener type="{ViewStreamEvent.START}" method="onViewStreamStart"/>
<mate:Listener type="{CursorEvent.UPDATE_CURSOR_LOC_EVENT}" method="onUpdateCursorEvent" />
<mate:Listener type="{ConnectionEvent.DESKSHARE_CONNECTION_EVENT}" method="onDeskshareConnectionEvent" />
<mx:Script>
<![CDATA[
import mx.core.UIComponent;
import org.as3commons.logging.api.ILogger;
import org.as3commons.logging.api.getClassLogger;
import org.bigbluebutton.common.Images;
import org.bigbluebutton.modules.deskshare.events.AppletStartedEvent;
import org.bigbluebutton.modules.deskshare.events.CursorEvent;
import org.bigbluebutton.modules.deskshare.events.ViewStreamEvent;
import org.bigbluebutton.modules.deskshare.services.DeskshareService;
import org.bigbluebutton.modules.deskshare.services.red5.ConnectionEvent;
import org.bigbluebutton.util.QueryStringParameters;
private static const LOGGER:ILogger = getClassLogger(DeskshareStandalone);
private var videoHolder:UIComponent;
private var cursor:Shape = new Shape();;
private var images:Images = new Images();
[Bindable] public var bbbLogo:Class = images.bbb_logo;
private var video:Video;
private var ns:NetStream;
private var stream:String;
private var logoutURL:String;
private var host:String;
private var room:String;
private var displayWidth:Number;
private var displayHeight:Number;
private var service:DeskshareService = new DeskshareService();
private var videoWidth:int;
private var videoHeight:int;
private function onCreationComplete():void {
var p:QueryStringParameters = new QueryStringParameters();
p.collectParameters();
logoutURL = p.getParameter("LOGOUTURL");
host = p.getParameter("HOST");
room = p.getParameter("ROOM");
service.connect(host, room);
cursor.graphics.lineStyle(6, 0xFF0000, 0.6);
cursor.graphics.drawCircle(0,0,3);
cursor.visible = false;
displayWidth = this.parent.width;
displayHeight = this.parent.height;
}
private function onAppletStart(event:AppletStartedEvent):void{
LOGGER.debug("DeskshareSA::onAppletStart.");
startVideo(service.getConnection(), room, event.videoWidth, event.videoHeight);
}
private function onViewStreamStart(event:ViewStreamEvent):void {
LOGGER.debug("DeskshareSA::onViewStreamStart.");
startVideo(service.getConnection(), room, event.videoWidth, event.videoHeight);
}
private function onAppletStop(event:ViewStreamEvent):void {
LOGGER.debug("DeskshareSA::onAppletStop.");
var url:URLRequest = new URLRequest(logoutURL);
navigateToURL(url, '_self');
}
private function onDeskshareConnectionEvent(event:ConnectionEvent):void {
var warningText:String;
switch(event.status) {
case ConnectionEvent.SUCCESS:
warningText = "Connecting to server successful.";
break;
case ConnectionEvent.FAILED:
warningText = "Connecting to server failed.";
break;
case ConnectionEvent.CLOSED:
warningText = "Connection to server closed.";
break;
case ConnectionEvent.REJECTED:
warningText = "Connection to server rejected.";
break;
case ConnectionEvent.INVALIDAPP:
warningText = "Connecting to server failed. Invalid application.";
break;
case ConnectionEvent.APPSHUTDOWN:
warningText = "Connection to server failed. Server shutting down.";
break;
case ConnectionEvent.SECURITYERROR:
warningText = "Connecting to server failed. Security error.";
break;
case ConnectionEvent.DISCONNECTED:
warningText = "Connection to server disconnected.";
break;
case ConnectionEvent.CONNECTING:
warningText = "Connecting to server...";
break;
case ConnectionEvent.CONNECTING_RETRY:
warningText = "Connecting to server failed. Retry [" + event.retryAttempts + "]";
break;
case ConnectionEvent.CONNECTING_MAX_RETRY:
warningText = "Connecting to server failed. Max retry reached. Giving up.";
break;
case ConnectionEvent.CHECK_FOR_DESKSHARE_STREAM:
warningText = "Loading...";
break;
case ConnectionEvent.FAIL_CHECK_FOR_DESKSHARE_STREAM:
warningText = "Loading shared desktop failed.";
break;
case ConnectionEvent.NO_DESKSHARE_STREAM:
warningText = "Desktop is not shared.";
break;
}
showStatusText(warningText, true, "0x000000");
LOGGER.debug("CONNECT STATUS EVENT [{0}]", [event.status]);
}
private function startVideo(connection:NetConnection, stream:String, videoWidth:Number, videoHeight:Number):void{
ns = new NetStream(connection);
ns.addEventListener( NetStatusEvent.NET_STATUS, onNetStatus );
ns.addEventListener(AsyncErrorEvent.ASYNC_ERROR, onAsyncError);
ns.client = this;
ns.bufferTime = 0;
ns.receiveVideo(true);
ns.receiveAudio(false);
video = new Video(videoWidth, videoHeight);
video.attachNetStream(ns);
this.videoWidth = videoWidth;
this.videoHeight = videoHeight;
videoHolder = new UIComponent();
LOGGER.debug("DeskshareSA::Determine how to display video = [{0}x{1}] display=[{2}x{3}]", [videoWidth, videoHeight, this.width, this.height]);
determineHowToDisplayVideo();
ns.play(stream);
this.stream = stream;
}
private function onMetaData(info:Object):void {
LOGGER.debug("DeskshareSA:: ****metadata: width={0} height={1}", [info.width, info.height]);
videoWidth = info.width;
videoHeight = info.height;
// determineHowToDisplayVideo();
}
private function onResize():void {
if (video != null) {
determineHowToDisplayVideo();
}
}
private function onUpdateCursorEvent(event:CursorEvent):void {
if (cursor == null) return;
cursor.x = videoHolder.x + (event.x * (videoHolder.width / videoWidth));
cursor.y = videoHolder.y + (event.y * (videoHolder.height / videoHeight));
cursorImg.visible = true;
// DO NOT compute the x and y coordinate and assign directly to the cursorImg
// as it results in a flickering and jerky mouse pointer (ralam jun 10, 2010).
cursorImg.x = cursor.x;
cursorImg.y = cursor.y;
}
public function stopViewing():void {
ns.close();
}
private function onAsyncError(e:AsyncErrorEvent):void{
LOGGER.debug("DeskshareSA::::asyncerror {0}", [e.toString()]);
}
private function onNetStatus(e:NetStatusEvent):void{
switch(e.info.code){
case "NetStream.Play.Start":
LOGGER.debug("DeskshareSA::NetStream.Publish.Start for broadcast stream {0}", [stream]);
LOGGER.debug("DeskshareSA::Dispatching start viewing event");
service.sendStartedViewingNotification(stream);
break;
case "NetStream.Play.UnpublishNotify":
LOGGER.debug("DeskshareSA::NetStream.Play.UnpublishNotify for broadcast stream {0}", [stream]);
stopViewing();
break;
case "NetStream.DRM.UpdateNeeded":
case "NetStream.Play.Failed":
case "NetStream.Play.FileStructureInvalid":
case "NetStream.Play.NoSupportedTrackFound":
case "NetStream.Play.StreamNotFound":
// case "NetStream.Play.Reset":
showStatusText(e.info.code, true, "0x000000");
break;
}
LOGGER.debug("NET STATUS EVENT [{0}]", [e.info.code]);
}
//----------------------------
private function centerToWindow():void{
videoHolder.width = video.width = videoWidth;
videoHolder.height = video.height = videoHeight;
videoHolder.x = video.x = (this.width - video.width) / 4;
videoHolder.y = video.y = (this.height - video.height) / 4;
LOGGER.debug("DeskshareSA::Center video = [{0}x{1}] display=[{2}x{3}]" + "loc=[{4},{5}]",
[video.width, video.height, this.width, this.height, videoHolder.x, videoHolder.y]);
videoHolder.addChild(video);
videoHolder.addChild(cursor);
videoHolder.addChild(cursorImg);
showVideoHolder();
}
private function fitVideoToWindow():void {
if (width < height) {
fitToWidthAndAdjustHeightToMaintainAspectRatio();
} else {
fitToHeightAndAdjustWidthToMaintainAspectRatio();
}
}
private function videoIsSmallerThanWindow():Boolean {
return (videoHeight < height) && (videoWidth < width);
}
private function fitToWidthAndAdjustHeightToMaintainAspectRatio():void {
LOGGER.debug("DeskshareSA::fitToWidthAndAdjustHeightToMaintainAspectRatio");
videoHolder.width = video.width = width;
// Maintain aspect-ratio
videoHolder.height = video.height = (videoHeight * video.width) / videoWidth;
videoHolder.x = video.x = 0;
videoHolder.y = video.y = 0;
LOGGER.debug("DeskshareSA::Disp video = [{0}x{1}] display=[{2}x{3}]" + "loc=[{4},{5}]",
[video.width, video.height, this.width, this.height, videoHolder.x, videoHolder.y]);
videoHolder.addChild(video);
videoHolder.addChild(cursor);
videoHolder.addChild(cursorImg);
showVideoHolder();
}
private function fitToHeightAndAdjustWidthToMaintainAspectRatio():void {
LOGGER.debug("DeskshareSA::fitToHeightAndAdjustWidthToMaintainAspectRatio");
videoHolder.height = video.height = height;
// Maintain aspect-ratio
videoHolder.width = video.width = (videoWidth * video.height) / videoHeight;
if (videoHolder.width > width) {
videoHolder.width = video.width = width;
videoHolder.height = video.height = (videoHeight * video.width) / videoWidth;
}
videoHolder.x = video.x = (width - video.width) / 4;
videoHolder.y = video.y = (height - video.height) / 4;
LOGGER.debug("DeskshareSA::Disp video = [{0}x{1}] display=[{2}x{3}]" + "loc=[{4},{5}]",
[video.width, video.height, this.width, this.height, videoHolder.x, videoHolder.y]);
videoHolder.addChild(video);
videoHolder.addChild(cursor);
videoHolder.addChild(cursorImg);
showVideoHolder();
}
private function showVideoHolder():void {
addChild(videoHolder);
}
private function determineHowToDisplayVideo():void {
// if (videoIsSmallerThanWindow()) {
// trace("Video is smaller than window. Centering.");
centerToWindow();
// } else {
// trace("Video is greater than window. Scaling.");
// fitVideoToWindow();
// }
}
private var hideStatusTextTimer:Timer = null;
private function showStatusText(statusText:String, autoHide:Boolean=false, color:String="0xFF0000"):void {
if (hideStatusTextTimer != null)
hideStatusTextTimer.stop();
if (autoHide) {
hideStatusTextTimer = new Timer(3000, 1);
hideStatusTextTimer.addEventListener(TimerEvent.TIMER, hideStatusText);
hideStatusTextTimer.start();
}
// bring the label to front
setChildIndex(statusTextDisplay, getChildren().length - 1);
statusTextDisplay.text = statusText;
statusTextDisplay.setStyle("color", color);
statusTextDisplay.visible = true;
}
private function hideStatusText(e:TimerEvent):void {
statusTextDisplay.visible = false;
}
]]>
</mx:Script>
<mx:Image id="cursorImg" visible="false" source="@Embed('org/bigbluebutton/modules/deskshare/assets/images/cursor4.png')"/>
<mx:Fade id="dissolveOut" duration="1000" alphaFrom="1.0" alphaTo="0.0"/>
<mx:Fade id="dissolveIn" duration="1000" alphaFrom="0.0" alphaTo="1.0"/>
<mx:Text id="statusTextDisplay" width="100%" fontSize="14" fontWeight="bold" textAlign="center" y="{(this.height - statusTextDisplay.height) / 2}"
visible="false" selectable="false" hideEffect="{dissolveOut}" showEffect="{dissolveIn}"/>
</mx:Application>

View File

@ -346,7 +346,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
]]> ]]>
</mx:Script> </mx:Script>
<mx:Image id="cursorImg" visible="false" source="@Embed('org/bigbluebutton/modules/deskshare/assets/images/cursor4.png')"/> <mx:Image id="cursorImg" visible="false" source="@Embed('org/bigbluebutton/modules/screenshare/assets/images/cursor4.png')"/>
<mx:Fade id="dissolveOut" duration="1000" alphaFrom="1.0" alphaTo="0.0"/> <mx:Fade id="dissolveOut" duration="1000" alphaFrom="1.0" alphaTo="0.0"/>
<mx:Fade id="dissolveIn" duration="1000" alphaFrom="0.0" alphaTo="1.0"/> <mx:Fade id="dissolveIn" duration="1000" alphaFrom="0.0" alphaTo="1.0"/>

View File

@ -38,7 +38,6 @@ package org.bigbluebutton.main.api
import org.bigbluebutton.main.model.users.events.EmojiStatusEvent; import org.bigbluebutton.main.model.users.events.EmojiStatusEvent;
import org.bigbluebutton.main.model.users.events.KickUserEvent; import org.bigbluebutton.main.model.users.events.KickUserEvent;
import org.bigbluebutton.main.model.users.events.RoleChangeEvent; import org.bigbluebutton.main.model.users.events.RoleChangeEvent;
import org.bigbluebutton.modules.deskshare.events.DeskshareAppletLaunchedEvent;
import org.bigbluebutton.modules.phone.events.AudioSelectionWindowEvent; import org.bigbluebutton.modules.phone.events.AudioSelectionWindowEvent;
import org.bigbluebutton.modules.phone.events.WebRTCCallEvent; import org.bigbluebutton.modules.phone.events.WebRTCCallEvent;
import org.bigbluebutton.modules.phone.events.WebRTCEchoTestEvent; import org.bigbluebutton.modules.phone.events.WebRTCEchoTestEvent;
@ -104,7 +103,6 @@ package org.bigbluebutton.main.api
ExternalInterface.addCallback("webRTCMediaRequest", handleWebRTCMediaRequest); ExternalInterface.addCallback("webRTCMediaRequest", handleWebRTCMediaRequest);
ExternalInterface.addCallback("webRTCMediaSuccess", handleWebRTCMediaSuccess); ExternalInterface.addCallback("webRTCMediaSuccess", handleWebRTCMediaSuccess);
ExternalInterface.addCallback("webRTCMediaFail", handleWebRTCMediaFail); ExternalInterface.addCallback("webRTCMediaFail", handleWebRTCMediaFail);
ExternalInterface.addCallback("javaAppletLaunched", handleJavaAppletLaunched);
ExternalInterface.addCallback("getSessionToken", handleGetSessionToken); ExternalInterface.addCallback("getSessionToken", handleGetSessionToken);
} }
@ -436,10 +434,5 @@ package org.bigbluebutton.main.api
private function handleWebRTCMediaFail():void { private function handleWebRTCMediaFail():void {
_dispatcher.dispatchEvent(new WebRTCMediaEvent(WebRTCMediaEvent.WEBRTC_MEDIA_FAIL)); _dispatcher.dispatchEvent(new WebRTCMediaEvent(WebRTCMediaEvent.WEBRTC_MEDIA_FAIL));
} }
private function handleJavaAppletLaunched():void
{
_dispatcher.dispatchEvent(new DeskshareAppletLaunchedEvent(DeskshareAppletLaunchedEvent.APPLET_LAUNCHED));
}
} }
} }

View File

@ -39,7 +39,9 @@ package org.bigbluebutton.main.events {
public var meetingId:String; public var meetingId:String;
public var breakoutId:String; public var breakoutMeetingId:String;
public var breakoutMeetingSequence:int;
public var rooms:Array; public var rooms:Array;

View File

@ -334,12 +334,11 @@ package org.bigbluebutton.main.model.users
private var _breakoutRooms : Array = []; private var _breakoutRooms : Array = [];
[Bindable("displayNameChange")] [Bindable("displayNameChange")]
public function get displayName() : String { public function get displayName():String {
if (ArrayUtils.isEmpty(_breakoutRooms)){ if (ArrayUtils.isEmpty(_breakoutRooms)) {
return name; return name;
} } else {
else { return "[" + _breakoutRooms.join(",") + "] " + name;
return "[" + _breakoutRooms.join(",") + "] " +name;
} }
} }
@ -352,14 +351,14 @@ package org.bigbluebutton.main.model.users
dispatchEvent(new Event("displayNameChange")); dispatchEvent(new Event("displayNameChange"));
} }
public function addBreakoutRoom(roomNumber:String):void { public function addBreakoutRoom(roomNumber:int):void {
if (!ArrayUtils.contains(_breakoutRooms, roomNumber)) { if (!ArrayUtils.contains(_breakoutRooms, roomNumber)) {
_breakoutRooms.push(roomNumber); _breakoutRooms.push(roomNumber);
dispatchEvent(new Event("displayNameChange")); dispatchEvent(new Event("displayNameChange"));
} }
} }
public function removeBreakoutRoom(roomNumber:String):void { public function removeBreakoutRoom(roomNumber:int):void {
_breakoutRooms.splice(_breakoutRooms.indexOf(roomNumber), 1); _breakoutRooms.splice(_breakoutRooms.indexOf(roomNumber), 1);
dispatchEvent(new Event("displayNameChange")); dispatchEvent(new Event("displayNameChange"));
} }

View File

@ -28,7 +28,11 @@ package org.bigbluebutton.main.model.users {
public static const OTHER:String = "other"; public static const OTHER:String = "other";
public var breakoutId:String; public var externalMeetingId:String;
public var meetingId:String;
public var sequence:int;
public var name:String; public var name:String;
@ -44,6 +48,5 @@ package org.bigbluebutton.main.model.users {
public function get numberOfUsers():int { public function get numberOfUsers():int {
return users.length; return users.length;
} }
} }
} }

View File

@ -20,6 +20,7 @@ package org.bigbluebutton.main.model.users {
import mx.collections.ArrayCollection; import mx.collections.ArrayCollection;
import mx.collections.Sort; import mx.collections.Sort;
import mx.collections.SortField;
import org.as3commons.lang.ArrayUtils; import org.as3commons.lang.ArrayUtils;
import org.as3commons.lang.StringUtils; import org.as3commons.lang.StringUtils;
@ -534,34 +535,40 @@ package org.bigbluebutton.main.model.users {
/* Breakout room feature */ /* Breakout room feature */
public function addBreakoutRoom(newRoom:BreakoutRoom):void { public function addBreakoutRoom(newRoom:BreakoutRoom):void {
if (hasBreakoutRoom(newRoom.breakoutId)) { if (hasBreakoutRoom(newRoom.meetingId)) {
removeBreakoutRoom(newRoom.breakoutId); removeBreakoutRoom(newRoom.meetingId);
} }
breakoutRooms.addItem(newRoom); breakoutRooms.addItem(newRoom);
sortBreakoutRooms();
}
private function sortBreakoutRooms() : void {
var sort:Sort = new Sort();
sort.fields = [new SortField("sequence", true, false, true)];
breakoutRooms.sort = sort;
breakoutRooms.refresh(); breakoutRooms.refresh();
} }
public function updateBreakoutRoomUsers(breakoutId:String, breakoutUsers:Array):void { public function updateBreakoutRoomUsers(breakoutMeetingId:String, breakoutUsers:Array):void {
var room:Object = getBreakoutRoom(breakoutId); var room:BreakoutRoom = getBreakoutRoom(breakoutMeetingId);
if (room != null) { if (room != null) {
BreakoutRoom(room).users = new ArrayCollection(breakoutUsers); room.users = new ArrayCollection(breakoutUsers);
var breakoutRoomNumber:String = StringUtils.substringAfterLast(breakoutId, "-");
var updateUsers:Array = []; var updateUsers:Array = [];
// Update users breakout rooms // Update users breakout rooms
var user : BBBUser; var user:BBBUser;
for (var i:int = 0; i < breakoutUsers.length; i++) { for (var i:int = 0; i < breakoutUsers.length; i++) {
var userId:String = StringUtils.substringBeforeLast(breakoutUsers[i].id, "-"); var userId:String = StringUtils.substringBeforeLast(breakoutUsers[i].id, "-");
user = getUser(userId); user = getUser(userId);
if (user) { if (user) {
user.addBreakoutRoom(breakoutRoomNumber) user.addBreakoutRoom(room.sequence)
} }
updateUsers.push(userId); updateUsers.push(userId);
} }
// Remove users breakout rooms if the users left the breakout rooms // Remove users breakout rooms if the users left the breakout rooms
for (var j:int = 0; j < users.length; j++) { for (var j:int = 0; j < users.length; j++) {
user = BBBUser(users.getItemAt(j)); user = BBBUser(users.getItemAt(j));
if (updateUsers.indexOf(BBBUser(users.getItemAt(j)).userID) == -1 && ArrayUtils.contains(user.breakoutRooms, breakoutRoomNumber)) { if (updateUsers.indexOf(BBBUser(users.getItemAt(j)).userID) == -1 && ArrayUtils.contains(user.breakoutRooms, room.sequence)) {
user.removeBreakoutRoom(breakoutRoomNumber); user.removeBreakoutRoom(room.sequence);
} }
} }
users.refresh(); users.refresh();
@ -569,24 +576,46 @@ package org.bigbluebutton.main.model.users {
} }
/** /**
* Returns a breakout room by its breakoutId * Returns a breakout room by its internal meeting ID
*/ */
public function getBreakoutRoom(breakoutId:String):BreakoutRoom { public function getBreakoutRoom(breakoutMeetingId:String):BreakoutRoom {
var r:Object = getBreakoutRoomIndex(breakoutId); var r:Object = getBreakoutRoomIndex(breakoutMeetingId);
if (r != null) { if (r != null) {
return r.room as BreakoutRoom; return r.room as BreakoutRoom;
} }
return null; return null;
} }
/** public function getBreakoutRoomByExternalId(externalId:String):BreakoutRoom {
* Finds the index of a breakout room by its breakoutId
*/
public function getBreakoutRoomIndex(breakoutId:String):Object {
var aRoom:BreakoutRoom; var aRoom:BreakoutRoom;
for (var i:int = 0; i < breakoutRooms.length; i++) { for (var i:int = 0; i < breakoutRooms.length; i++) {
aRoom = breakoutRooms.getItemAt(i) as BreakoutRoom; aRoom = breakoutRooms.getItemAt(i) as BreakoutRoom;
if (aRoom.breakoutId == breakoutId) { if (aRoom.externalMeetingId == externalId) {
return aRoom;
}
}
return null;
}
public function getBreakoutRoomBySequence(sequence:int):BreakoutRoom {
var aRoom:BreakoutRoom;
for (var i:int = 0; i < breakoutRooms.length; i++) {
aRoom = breakoutRooms.getItemAt(i) as BreakoutRoom;
if (aRoom.sequence == sequence) {
return aRoom;
}
}
return null;
}
/**
* Finds the index of a breakout room by its internal meeting ID
*/
public function getBreakoutRoomIndex(breakoutMeetingId:String):Object {
var aRoom:BreakoutRoom;
for (var i:int = 0; i < breakoutRooms.length; i++) {
aRoom = breakoutRooms.getItemAt(i) as BreakoutRoom;
if (aRoom.meetingId == breakoutMeetingId) {
return {index: i, room: aRoom}; return {index: i, room: aRoom};
} }
} }
@ -594,39 +623,38 @@ package org.bigbluebutton.main.model.users {
return null; return null;
} }
public function removeBreakoutRoom(breakoutId:String):void { public function removeBreakoutRoom(breakoutMeetingId:String):void {
var p:Object = getBreakoutRoomIndex(breakoutId); var room:Object = getBreakoutRoomIndex(breakoutMeetingId);
if (p != null) { if (room != null) {
breakoutRooms.removeItemAt(p.index); breakoutRooms.removeItemAt(room.index);
breakoutRooms.refresh(); sortBreakoutRooms();
if (breakoutRooms.length == 0) { if (breakoutRooms.length == 0) {
breakoutRoomsReady = false; breakoutRoomsReady = false;
} }
// Remove breakout room number display from users // Remove breakout room number display from users
for (var i:int; i < users.length; i++) { for (var i:int; i < users.length; i++) {
var breakoutRoomNumber:String = StringUtils.substringAfterLast(breakoutId, "-"); if (ArrayUtils.contains(users[i].breakoutRooms, room.room.sequence)) {
if (ArrayUtils.contains(users[i].breakoutRooms, breakoutRoomNumber)) { users[i].removeBreakoutRoom(room.room.sequence);
users[i].removeBreakoutRoom(breakoutRoomNumber);
} }
} }
users.refresh(); users.refresh();
} }
} }
public function hasBreakoutRoom(breakoutId:String):Boolean { public function hasBreakoutRoom(breakoutMeetingId:String):Boolean {
var p:Object = getBreakoutRoomIndex(breakoutId); var p:Object = getBreakoutRoomIndex(breakoutMeetingId);
if (p != null) { if (p != null) {
return true; return true;
} }
return false; return false;
} }
public function setBreakoutRoomInListen(listen:Boolean, breakoutId:String):void { public function setBreakoutRoomInListen(listen:Boolean, breakoutMeetingId:String):void {
for (var i:int = 0; i < breakoutRooms.length; i++) { for (var i:int = 0; i < breakoutRooms.length; i++) {
var br:BreakoutRoom = BreakoutRoom(breakoutRooms.getItemAt(i)); var br:BreakoutRoom = BreakoutRoom(breakoutRooms.getItemAt(i));
if (listen == false) { if (listen == false) {
br.listenStatus = BreakoutRoom.NONE; br.listenStatus = BreakoutRoom.NONE;
} else if (listen == true && br.breakoutId == breakoutId) { } else if (listen == true && br.meetingId == breakoutMeetingId) {
br.listenStatus = BreakoutRoom.SELF; br.listenStatus = BreakoutRoom.SELF;
} else { } else {
br.listenStatus = BreakoutRoom.OTHER; br.listenStatus = BreakoutRoom.OTHER;

View File

@ -199,20 +199,20 @@ package org.bigbluebutton.main.model.users
} }
public function createBreakoutRooms(e:BreakoutRoomEvent):void{ public function createBreakoutRooms(e:BreakoutRoomEvent):void{
sender.createBreakoutRooms(_conferenceParameters.meetingID, e.rooms, e.durationInMinutes, e.record); sender.createBreakoutRooms(_conferenceParameters.meetingID, e.rooms, e.durationInMinutes, e.record, true);
} }
public function requestBreakoutJoinUrl(e:BreakoutRoomEvent):void{ public function requestBreakoutJoinUrl(e:BreakoutRoomEvent):void{
sender.requestBreakoutJoinUrl(_conferenceParameters.meetingID, e.breakoutId, e.userId); sender.requestBreakoutJoinUrl(_conferenceParameters.meetingID, e.breakoutMeetingId, e.userId, true);
} }
public function listenInOnBreakout(e:BreakoutRoomEvent):void { public function listenInOnBreakout(e:BreakoutRoomEvent):void {
if (e.listen) { if (e.listen) {
sender.listenInOnBreakout(_conferenceParameters.meetingID, e.breakoutId, _conferenceParameters.userid); sender.listenInOnBreakout(_conferenceParameters.meetingID, e.breakoutMeetingId, _conferenceParameters.userid);
} else { } else {
sender.listenInOnBreakout(e.breakoutId, _conferenceParameters.meetingID, _conferenceParameters.userid); sender.listenInOnBreakout(e.breakoutMeetingId, _conferenceParameters.meetingID, _conferenceParameters.userid);
} }
UserManager.getInstance().getConference().setBreakoutRoomInListen(e.listen, e.breakoutId); UserManager.getInstance().getConference().setBreakoutRoomInListen(e.listen, e.breakoutMeetingId);
} }
public function endAllBreakoutRooms(e:BreakoutRoomEvent):void { public function endAllBreakoutRooms(e:BreakoutRoomEvent):void {

View File

@ -94,6 +94,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
messages.push(obj); messages.push(obj);
showNotification(); showNotification();
LOGGER.warn("ClientNotification:" + e.title + " " + e.message);
} }
private function showNotification():void { private function showNotification():void {

Binary file not shown.

Before

Width:  |  Height:  |  Size: 551 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 342 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 332 B

View File

@ -1,36 +0,0 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 3.0 of the License, or (at your option) any later
* version.
*
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.modules.deskshare.events
{
import flash.events.Event;
public class CursorEvent extends Event
{
public static const UPDATE_CURSOR_LOC_EVENT:String = "Update sharer cursor event";
public var x:Number = 0;
public var y:Number = 0;
public function CursorEvent(type:String, bubbles:Boolean=true, cancelable:Boolean=false)
{
super(type, bubbles, cancelable);
}
}
}

View File

@ -1,14 +0,0 @@
package org.bigbluebutton.modules.deskshare.events
{
import flash.events.Event;
public class DeskshareAppletLaunchedEvent extends Event
{
public static const APPLET_LAUNCHED:String = "DESKSHARE_APPLET_LAUNCHED_EVENT";
public function DeskshareAppletLaunchedEvent(type:String, bubbles:Boolean=false, cancelable:Boolean=false)
{
super(type, bubbles, cancelable);
}
}
}

View File

@ -1,39 +0,0 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 3.0 of the License, or (at your option) any later
* version.
*
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.modules.deskshare.events
{
import flash.events.Event;
import org.bigbluebutton.common.IBigBlueButtonModule;
public class ModuleEvent extends Event
{
public static const START:String = "Deskshare Module Start Event";
public static const STOP:String = "Deskshare Module Stop Event";
public var module:IBigBlueButtonModule;
public function ModuleEvent(type:String, bubbles:Boolean=true, cancelable:Boolean=false)
{
this.module = module;
super(type, bubbles, cancelable);
}
}
}

View File

@ -1,40 +0,0 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 3.0 of the License, or (at your option) any later
* version.
*
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.modules.deskshare.events
{
import flash.events.Event;
public class RecordingStatusEvent extends Event
{
public static const DESKSHARE_RECORD_EVENT:String = "DESKSHARE_RECORD_EVENT";
public static const RECORD_STOPPED_EVENT:String = "DESKSHARE_RECORD_STOPPED_EVENT";
public static const RECORD_STARTED_EVENT:String = "DESKSHARE_RECORD_STARTED_EVENT";
public static const RECORD_UPDATED_EVENT:String = "DESKSHARE_RECORD_UPDATED_EVENT";
public static const RECORD_ERROR_EVENT:String = "DESKSHARE_RECORD_ERROR_EVENT";
public var status:String;
public function RecordingStatusEvent(type:String, bubbles:Boolean=true, cancelable:Boolean=false)
{
super(type, bubbles, cancelable);
}
}
}

View File

@ -1,34 +0,0 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 3.0 of the License, or (at your option) any later
* version.
*
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.modules.deskshare.events
{
import flash.events.Event;
public class ShareEvent extends Event
{
public static const START_SHARING:String = "START SHARING";
public static const STOP_SHARING:String = "STOP SHARING";
public function ShareEvent(type:String, bubbles:Boolean=true, cancelable:Boolean=false)
{
super(type, bubbles, cancelable);
}
}
}

View File

@ -1,33 +0,0 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 3.0 of the License, or (at your option) any later
* version.
*
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.modules.deskshare.events
{
import flash.events.Event;
public class ShareWindowEvent extends Event
{
public static const CLOSE:String = "Deskshare Share Window Close Event";
public function ShareWindowEvent(type:String, bubbles:Boolean=true, cancelable:Boolean=false)
{
super(type, bubbles, cancelable);
}
}
}

View File

@ -1,35 +0,0 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 3.0 of the License, or (at your option) any later
* version.
*
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.modules.deskshare.events
{
import flash.events.Event;
public class StartedViewingEvent extends Event
{
public static const STARTED_VIEWING_EVENT:String = "STARTED VIEWING DESKSHARE EVENT";
public var stream:String;
public function StartedViewingEvent(type: String, bubbles:Boolean=true, cancelable:Boolean=false)
{
super(type, bubbles, cancelable);
}
}
}

View File

@ -1,33 +0,0 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 3.0 of the License, or (at your option) any later
* version.
*
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.modules.deskshare.events
{
import flash.events.Event;
public class StopSharingButtonEvent extends Event
{
public static const STOP_SHARING:String = "Stop Sharing Event";
public function StopSharingButtonEvent(type:String)
{
super(type, true, false);
}
}
}

View File

@ -1,37 +0,0 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 3.0 of the License, or (at your option) any later
* version.
*
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.modules.deskshare.events
{
import flash.events.Event;
public class StreamEvent extends Event
{
public static const START:String = "Deskshare Stream Started Event";
public static const STOP:String = "Deskshare Stream Stopped Event";
public var videoWidth:Number = 0;
public var videoHeight:Number = 0;
public function StreamEvent(type:String, bubbles:Boolean=true, cancelable:Boolean=false)
{
super(type, bubbles, cancelable);
}
}
}

View File

@ -1,14 +0,0 @@
package org.bigbluebutton.modules.deskshare.events
{
import flash.events.Event;
public class UseJavaModeCommand extends Event
{
public static const USE_JAVA_MODE:String = "use Java to join deskshare event";
public function UseJavaModeCommand()
{
super(USE_JAVA_MODE, true, false);
}
}
}

View File

@ -1,37 +0,0 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 3.0 of the License, or (at your option) any later
* version.
*
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.modules.deskshare.events
{
import flash.events.Event;
public class ViewStreamEvent extends Event
{
public static const START:String = "Start Viewing Stream Event";
public static const STOP:String = "Stop Viewing Stream Event";
public var videoWidth:Number = 0;
public var videoHeight:Number = 0;
public function ViewStreamEvent(type:String, bubbles:Boolean=true, cancelable:Boolean=false)
{
super(type, bubbles, cancelable);
}
}
}

View File

@ -1,33 +0,0 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 3.0 of the License, or (at your option) any later
* version.
*
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.modules.deskshare.events
{
import flash.events.Event;
public class ViewWindowEvent extends Event
{
public static const CLOSE:String = "Deskshare View Window Close Event";
public function ViewWindowEvent(type:String, bubbles:Boolean=true, cancelable:Boolean=false)
{
super(type, bubbles, cancelable);
}
}
}

View File

@ -1,33 +0,0 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2015 BigBlueButton Inc. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 3.0 of the License, or (at your option) any later
* version.
*
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.modules.deskshare.events
{
import flash.events.Event;
public class WebRTCShareWindowEvent extends Event
{
public static const CLOSE:String = "WebRTC Deskshare Share Window Close Event";
public function WebRTCShareWindowEvent(type:String, bubbles:Boolean=true, cancelable:Boolean=false)
{
super(type, bubbles, cancelable);
}
}
}

View File

@ -1,37 +0,0 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2015 BigBlueButton Inc. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 3.0 of the License, or (at your option) any later
* version.
*
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.modules.deskshare.events
{
import flash.events.Event;
public class WebRTCStreamEvent extends Event
{
public static const START:String = "WebRTC Deskshare Stream Started Event";
public static const STOP:String = "WebRTC Deskshare Stream Stopped Event";
public var videoWidth:Number = 0;
public var videoHeight:Number = 0;
public function WebRTCStreamEvent(type:String, bubbles:Boolean=true, cancelable:Boolean=false)
{
super(type, bubbles, cancelable);
}
}
}

View File

@ -1,41 +0,0 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2015 BigBlueButton Inc. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 3.0 of the License, or (at your option) any later
* version.
*
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.modules.deskshare.events
{
import flash.events.Event;
import org.bigbluebutton.main.api.JSLog;
public class WebRTCViewStreamEvent extends Event
{
public static const START:String = "WebRTC Start Viewing Stream Event";
public static const STOP:String = "WebRTC Stop Viewing Stream Event";
public var videoWidth:Number = 0;
public var videoHeight:Number = 0;
public var rtmp:String = null;
public function WebRTCViewStreamEvent(type:String, bubbles:Boolean=true, cancelable:Boolean=false)
{
super(type, bubbles, cancelable);
JSLog.warn("creating a WebRTCViewStreamEvent event " + type, null);
}
}
}

View File

@ -1,33 +0,0 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2015 BigBlueButton Inc. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 3.0 of the License, or (at your option) any later
* version.
*
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.modules.deskshare.events
{
import flash.events.Event;
public class WebRTCViewWindowEvent extends Event
{
public static const CLOSE:String = "WebRTC Deskshare View Window Close Event";
public function WebRTCViewWindowEvent(type:String, bubbles:Boolean=true, cancelable:Boolean=false)
{
super(type, bubbles, cancelable);
}
}
}

View File

@ -1,174 +0,0 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 3.0 of the License, or (at your option) any later
* version.
*
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.modules.deskshare.managers
{
import com.asfusion.mate.events.Dispatcher;
import org.as3commons.logging.api.ILogger;
import org.as3commons.logging.api.getClassLogger;
import org.bigbluebutton.core.UsersUtil;
import org.bigbluebutton.main.events.MadePresenterEvent;
import org.bigbluebutton.modules.deskshare.events.UseJavaModeCommand;
import org.bigbluebutton.modules.deskshare.model.DeskshareOptions;
import org.bigbluebutton.modules.deskshare.services.DeskshareService;
import org.bigbluebutton.modules.deskshare.utils.JavaCheck;
import org.bigbluebutton.modules.deskshare.utils.BrowserCheck;
import flash.external.ExternalInterface;
public class DeskshareManager {
private static const LOGGER:ILogger = getClassLogger(DeskshareManager);
private var publishWindowManager:PublishWindowManager;
private var viewWindowManager:ViewerWindowManager;
private var toolbarButtonManager:ToolbarButtonManager;
private var module:DeskShareModule;
private var service:DeskshareService;
private var globalDispatcher:Dispatcher;
private var sharing:Boolean = false;
private var usingJava:Boolean = true;
public function DeskshareManager() {
service = new DeskshareService();
globalDispatcher = new Dispatcher();
publishWindowManager = new PublishWindowManager(service);
viewWindowManager = new ViewerWindowManager(service);
toolbarButtonManager = new ToolbarButtonManager();
}
public function handleStartModuleEvent(module:DeskShareModule):void {
LOGGER.debug("Deskshare Module starting");
this.module = module;
service.handleStartModuleEvent(module);
if (UsersUtil.amIPresenter()) {
initDeskshare();
}
}
public function handleStopModuleEvent():void {
LOGGER.debug("Deskshare Module stopping");
publishWindowManager.stopSharing();
viewWindowManager.stopViewing();
service.disconnect();
}
public function handleStreamStoppedEvent():void {
LOGGER.debug("Sending deskshare stopped command");
service.stopSharingDesktop(module.getRoom(), module.getRoom());
}
public function handleStreamStartedEvent(videoWidth:Number, videoHeight:Number):void {
LOGGER.debug("Sending startViewing command");
service.sendStartViewingNotification(videoWidth, videoHeight);
}
public function handleStartedViewingEvent(stream:String):void {
LOGGER.debug("handleStartedViewingEvent [{0}]", [stream]);
service.sendStartedViewingNotification(stream);
}
private function initDeskshare():void {
sharing = false;
var options:DeskshareOptions = new DeskshareOptions();
options.parseOptions();
if (options.autoStart) {
handleStartSharingEvent(true);
}
if(options.showButton){
toolbarButtonManager.addToolbarButton();
}
}
public function handleMadePresenterEvent(e:MadePresenterEvent):void {
LOGGER.debug("Got MadePresenterEvent ");
initDeskshare();
}
public function handleMadeViewerEvent(e:MadePresenterEvent):void{
LOGGER.debug("Got MadeViewerEvent ");
toolbarButtonManager.removeToolbarButton();
if (sharing) {
publishWindowManager.stopSharing();
}
sharing = false;
}
public function handleStartSharingEvent(autoStart:Boolean):void {
LOGGER.debug("DeskshareManager::handleStartSharingEvent (Java)");
var options:DeskshareOptions = new DeskshareOptions();
options.parseOptions();
// falling back to java, or we can't use WebRTC
if (autoStart || (options.useWebRTCIfAvailable && !BrowserCheck.isWebRTCSupported())) {
if (BrowserCheck.isUsingLessThanChrome38OnMac()) {
usingJava = false;
publishWindowManager.startSharing(options.publishURI , options.useTLS , module.getRoom(), autoStart, options.autoFullScreen);
} else {
var javaIssue:String = JavaCheck.checkJava();
if (javaIssue != null) {
if (BrowserCheck.isChrome42OrHigher()) {
usingJava = false;
publishWindowManager.startSharing(options.publishURI , options.useTLS , module.getRoom(), autoStart, options.autoFullScreen);
} else {
usingJava = false;
publishWindowManager.startSharing(options.publishURI , options.useTLS , module.getRoom(), autoStart, options.autoFullScreen);
}
} else {
usingJava = true;
toolbarButtonManager.startedSharing();
publishWindowManager.startSharing(options.publishURI , options.useTLS , module.getRoom(), autoStart, options.autoFullScreen);
sharing = true;
}
}
} else {
// using WebRTC or not a fallback case
usingJava = false;
}
}
public function handleShareWindowCloseEvent():void {
//toolbarButtonManager.enableToolbarButton();
publishWindowManager.handleShareWindowCloseEvent();
sharing = false;
toolbarButtonManager.stopedSharing();
}
public function handleViewWindowCloseEvent():void {
LOGGER.debug("Received stop viewing command");
viewWindowManager.handleViewWindowCloseEvent();
}
public function handleStreamStartEvent(videoWidth:Number, videoHeight:Number):void{
if (!usingJava) { return; }
if (sharing) { return; }
LOGGER.debug("Received start viewing command");
viewWindowManager.startViewing(module.getRoom(), videoWidth, videoHeight);
}
public function handleUseJavaModeCommand():void {
usingJava = true;
handleStartSharingEvent(true);
}
}
}

View File

@ -1,107 +0,0 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 3.0 of the License, or (at your option) any later
* version.
*
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.modules.deskshare.managers
{
import com.asfusion.mate.events.Dispatcher;
import flash.events.TimerEvent;
import flash.utils.Timer;
import org.as3commons.logging.api.ILogger;
import org.as3commons.logging.api.getClassLogger;
import org.bigbluebutton.common.IBbbModuleWindow;
import org.bigbluebutton.common.events.CloseWindowEvent;
import org.bigbluebutton.common.events.OpenWindowEvent;
import org.bigbluebutton.modules.deskshare.services.DeskshareService;
import org.bigbluebutton.modules.deskshare.view.components.DesktopPublishWindow;
public class PublishWindowManager {
private static const LOGGER:ILogger = getClassLogger(PublishWindowManager);
private var shareWindow:DesktopPublishWindow;
private var globalDispatcher:Dispatcher;
private var service:DeskshareService;
private var buttonShownOnToolbar:Boolean = false;
private var isOpen:Boolean = false;
// Timer to auto-publish webcam. We need this timer to delay
// the auto-publishing until after the Viewers's window has loaded
// to receive the publishing events. Otherwise, the user joining next
// won't be able to view the webcam.
private var autoPublishTimer:Timer;
public function PublishWindowManager(service:DeskshareService) {
LOGGER.debug("PublishWindowManager init");
globalDispatcher = new Dispatcher();
this.service = service;
}
public function stopSharing():void {
if (shareWindow != null) {
shareWindow.stopSharing();
isOpen = false;
}
}
public function startSharing(uri:String , useTLS:Boolean , room:String, autoStart:Boolean, autoFullScreen:Boolean):void {
LOGGER.debug("DS:PublishWindowManager::opening desk share window, autostart={0} autoFullScreen={1}", [autoStart, autoFullScreen]);
if (isOpen) {
return;
}
isOpen = true;
shareWindow = new DesktopPublishWindow();
shareWindow.initWindow(service.getConnection(), uri , useTLS , room, autoStart, autoFullScreen);
shareWindow.visible = true;
openWindow(shareWindow);
if (autoStart || autoFullScreen) {
/*
* Need to have a timer to trigger auto-publishing of deskshare.
*/
shareWindow.btnFSPublish.enabled = false;
shareWindow.btnRegionPublish.enabled = false;
autoPublishTimer = new Timer(2000, 1);
autoPublishTimer.addEventListener(TimerEvent.TIMER, autopublishTimerHandler);
autoPublishTimer.start();
}
}
private function autopublishTimerHandler(event:TimerEvent):void {
shareWindow.shareScreen(true);
}
public function handleShareWindowCloseEvent():void {
closeWindow(shareWindow);
}
private function openWindow(window:IBbbModuleWindow):void {
isOpen = true;
var event:OpenWindowEvent = new OpenWindowEvent(OpenWindowEvent.OPEN_WINDOW_EVENT);
event.window = window;
globalDispatcher.dispatchEvent(event);
}
private function closeWindow(window:IBbbModuleWindow):void {
isOpen = false;
var event:CloseWindowEvent = new CloseWindowEvent(CloseWindowEvent.CLOSE_WINDOW_EVENT);
event.window = window;
globalDispatcher.dispatchEvent(event);
}
}
}

View File

@ -1,85 +0,0 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 3.0 of the License, or (at your option) any later
* version.
*
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.modules.deskshare.managers
{
import com.asfusion.mate.events.Dispatcher;
import org.as3commons.logging.api.ILogger;
import org.as3commons.logging.api.getClassLogger;
import org.bigbluebutton.common.events.ToolbarButtonEvent;
import org.bigbluebutton.modules.deskshare.view.components.ToolbarButton;
public class ToolbarButtonManager {
private static const LOGGER:ILogger = getClassLogger(ToolbarButtonManager);
private var button:ToolbarButton;
private var isSharing:Boolean = false;
private var globalDispatcher:Dispatcher;
private var buttonShownOnToolbar:Boolean = false;
public function ToolbarButtonManager() {
globalDispatcher = new Dispatcher();
button = new ToolbarButton();
}
public function addToolbarButton():void {
LOGGER.debug("DeskShare::addToolbarButton");
if ((button != null) && (!buttonShownOnToolbar)) {
button = new ToolbarButton();
/* Test */ //button.tabIndex=4;
var event:ToolbarButtonEvent = new ToolbarButtonEvent(ToolbarButtonEvent.ADD);
event.button = button;
event.module="DeskShare";
//event.tabIndex = 0;
globalDispatcher.dispatchEvent(event);
buttonShownOnToolbar = true;
button.enabled = true;
}
}
public function removeToolbarButton():void {
if (buttonShownOnToolbar) {
var event:ToolbarButtonEvent = new ToolbarButtonEvent(ToolbarButtonEvent.REMOVE);
event.button = button;
globalDispatcher.dispatchEvent(event);
buttonShownOnToolbar = false;
}
}
//OLD - CAN BE DELETED
public function enableToolbarButton():void {
button.enabled = true;
button.stopDeskshare();
}
//OLD - CAN BE DELETED
public function disableToolbarButton():void {
button.enabled = false;
}
public function startedSharing():void {
button.deskshareStatus(button.START_SHARING);
}
public function stopedSharing():void {
button.deskshareStatus(button.STOP_SHARING);
}
}
}

View File

@ -1,81 +0,0 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 3.0 of the License, or (at your option) any later
* version.
*
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.modules.deskshare.managers
{
import com.asfusion.mate.events.Dispatcher;
import org.as3commons.logging.api.ILogger;
import org.as3commons.logging.api.getClassLogger;
import org.bigbluebutton.common.IBbbModuleWindow;
import org.bigbluebutton.common.events.CloseWindowEvent;
import org.bigbluebutton.common.events.OpenWindowEvent;
import org.bigbluebutton.modules.deskshare.services.DeskshareService;
import org.bigbluebutton.modules.deskshare.view.components.DesktopViewWindow;
public class ViewerWindowManager {
private static const LOGGER:ILogger = getClassLogger(ViewerWindowManager);
private var viewWindow:DesktopViewWindow;
private var service:DeskshareService;
private var isViewing:Boolean = false;
private var globalDispatcher:Dispatcher;
public function ViewerWindowManager(service:DeskshareService) {
this.service = service;
globalDispatcher = new Dispatcher();
}
public function stopViewing():void {
if (isViewing) viewWindow.stopViewing();
}
public function handleStartedViewingEvent(stream:String):void{
LOGGER.debug("ViewerWindowManager handleStartedViewingEvent");
service.sendStartedViewingNotification(stream);
}
private function openWindow(window:IBbbModuleWindow):void{
var event:OpenWindowEvent = new OpenWindowEvent(OpenWindowEvent.OPEN_WINDOW_EVENT);
event.window = window;
globalDispatcher.dispatchEvent(event);
}
public function handleViewWindowCloseEvent():void {
LOGGER.debug("ViewerWindowManager Received stop viewing command");
closeWindow(viewWindow);
isViewing = false;
}
private function closeWindow(window:IBbbModuleWindow):void {
var event:CloseWindowEvent = new CloseWindowEvent(CloseWindowEvent.CLOSE_WINDOW_EVENT);
event.window = window;
globalDispatcher.dispatchEvent(event);
}
public function startViewing(room:String, videoWidth:Number, videoHeight:Number):void{
LOGGER.debug("ViewerWindowManager::startViewing");
viewWindow = new DesktopViewWindow();
viewWindow.startVideo(service.getConnection(), room, videoWidth, videoHeight);
openWindow(viewWindow);
isViewing = true;
}
}
}

View File

@ -1,264 +0,0 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2015 BigBlueButton Inc. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 3.0 of the License, or (at your option) any later
* version.
*
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.modules.deskshare.managers
{
import com.asfusion.mate.events.Dispatcher;
import flash.external.ExternalInterface;
import org.as3commons.logging.api.ILogger;
import org.as3commons.logging.api.getClassLogger;
import org.bigbluebutton.core.UsersUtil;
import org.bigbluebutton.core.managers.UserManager;
import org.bigbluebutton.main.events.MadePresenterEvent;
import org.bigbluebutton.modules.deskshare.events.UseJavaModeCommand;
import org.bigbluebutton.modules.deskshare.events.WebRTCViewStreamEvent;
import org.bigbluebutton.modules.deskshare.model.DeskshareOptions;
import org.bigbluebutton.modules.deskshare.events.ShareWindowEvent;
import org.bigbluebutton.modules.deskshare.services.WebRTCDeskshareService;
import org.bigbluebutton.modules.deskshare.utils.BrowserCheck;
import org.bigbluebutton.main.api.JSLog;
public class WebRTCDeskshareManager {
private static const LOGGER:ILogger = getClassLogger(WebRTCDeskshareManager);
private var publishWindowManager:WebRTCPublishWindowManager;
private var viewWindowManager:WebRTCViewerWindowManager;
private var toolbarButtonManager:ToolbarButtonManager;
private var module:DeskShareModule;
private var service:WebRTCDeskshareService;
private var globalDispatcher:Dispatcher;
private var sharing:Boolean = false;
private var usingWebRTC:Boolean = false;
private var chromeExtensionKey:String = null;
private var vertoServerCredentials:Object = new Object();
public function WebRTCDeskshareManager() {
service = new WebRTCDeskshareService();
globalDispatcher = new Dispatcher();
publishWindowManager = new WebRTCPublishWindowManager(service);
viewWindowManager = new WebRTCViewerWindowManager(service);
}
public function handleStartModuleEvent(module:DeskShareModule):void {
LOGGER.debug("WebRTC Deskshare Module starting");
this.module = module;
service.handleStartModuleEvent(module);
if (UsersUtil.amIPresenter()) {
initDeskshare();
}
}
public function handleStopModuleEvent():void {
LOGGER.debug("WebRTC Deskshare Module stopping");
publishWindowManager.stopSharing();
viewWindowManager.stopViewing();
service.disconnect();
}
/*presenter stopped their program stream*/
public function handleStreamStoppedEvent():void {
LOGGER.debug("DeskshareManager::handleStreamStoppedEvent Sending deskshare stopped command");
JSLog.warn("WebRTCDeskshareManager::handleStreamStoppedEvent", {});
stopWebRTCDeskshare();
}
/*viewer being told there is no more stream*/
public function handleStreamStopEvent(args:Object):void {
LOGGER.debug("WebRTCDeskshareManager::handleStreamStopEvent");
JSLog.warn("WebRTCDeskshareManager::handleStreamStopEvent", {});
viewWindowManager.handleViewWindowCloseEvent();
}
private function stopWebRTCDeskshare():void {
LOGGER.debug("DeskshareManager::stopWebRTCDeskshare");
viewWindowManager.stopViewing();
/* stopping WebRTC deskshare. Alert DeskshareManager to reset toolbar */
globalDispatcher.dispatchEvent(new ShareWindowEvent(ShareWindowEvent.CLOSE));
if (ExternalInterface.available) {
var loggingCallback:Function = function(args:Object):void {LOGGER.debug(args); JSLog.warn("loggingCallback", args)};
var onSuccess:Function = function():void { LOGGER.debug("onSuccess"); JSLog.warn("onSuccess - as", {})};
ExternalInterface.addCallback("loggingCallback", loggingCallback);
ExternalInterface.addCallback("onSuccess", onSuccess);
ExternalInterface.call("endScreenshare", "loggingCallback", "onSuccess");
} else {
LOGGER.error("Error! ExternalInterface not available (webrtcDeskshare)");
}
}
private function startWebRTCDeskshare():void {
LOGGER.debug("DeskshareManager::startWebRTCDeskshare");
if (ExternalInterface.available) {
var videoTag:String = "localVertoVideo";
var onFail:Function = function(args:Object):void {
JSLog.warn("onFail - as", args);
JSLog.warn("WebRTCDeskshareManager::startWebRTCDeskshare - falling back to java", {});
globalDispatcher.dispatchEvent(new UseJavaModeCommand())
};
ExternalInterface.addCallback("onFail", onFail);
ExternalInterface.call(
'vertoShareScreen',
videoTag,
'3500',
'FreeSWITCH USers - abc',
'1008',
null,
vertoServerCredentials,
chromeExtensionKey,
onFail
);
}
}
private function initDeskshare():void {
sharing = false;
var options:DeskshareOptions = new DeskshareOptions();
options.parseOptions();
if (options.chromeExtensionKey) {
chromeExtensionKey = options.chromeExtensionKey;
}
if (options.vertoPort) {
vertoServerCredentials.vertoPort = options.vertoPort;
}
if (options.hostName) {
vertoServerCredentials.hostName = options.hostName;
}
if (options.login) {
vertoServerCredentials.login = options.login;
}
if (options.password) {
vertoServerCredentials.password = options.password;
}
if (options.autoStart) {
handleStartSharingEvent(true);
}
}
public function handleMadePresenterEvent(e:MadePresenterEvent):void {
LOGGER.debug("Got MadePresenterEvent ");
initDeskshare();
}
public function handleMadeViewerEvent(e:MadePresenterEvent):void{
LOGGER.debug("Got MadeViewerEvent ");
if (sharing) {
publishWindowManager.stopSharing();
stopWebRTCDeskshare();
}
sharing = false;
}
private function canIUseVertoOnThisBrowser(onFailure:Function, onSuccess:Function):void {
LOGGER.debug("DeskshareManager::canIUseVertoOnThisBrowser");
var options:DeskshareOptions = new DeskshareOptions();
options.parseOptions();
if (options.useWebRTCIfAvailable && BrowserCheck.isWebRTCSupported()) {
JSLog.warn("WebRTCDeskshareManager::handleStartSharingEvent WebRTC Supported", {});
if (BrowserCheck.isFirefox()) {
onSuccess("Firefox, lets try");
} else {
if (chromeExtensionKey != null) {
/*toolbarButtonManager.startedSharing();*/
JSLog.warn("WebRTCDeskshareManager::handleStartSharingEvent chrome extension key exists - ", chromeExtensionKey);
if (ExternalInterface.available) {
var success:Function = function(status:String):void {
ExternalInterface.addCallback("callback", null);
JSLog.warn("WebRTCDeskshareManager::handleStartSharingEvent inside onSuccess", {});
if (status == "installed-enabled") {
JSLog.warn("Chrome Extension exists", {});
onSuccess("worked");
} else {
onFailure("No Chrome Extension");
}
};
ExternalInterface.addCallback("callback", success);
ExternalInterface.call("getChromeExtensionStatus", chromeExtensionKey, "callback");
}
} else {
onFailure("No chromeExtensionKey in config.xml");
return;
}
}
} else {
onFailure("Web browser doesn't support WebRTC");
return;
}
}
/*handle start sharing event*/
public function handleStartSharingEvent(autoStart:Boolean):void {
LOGGER.debug("WebRTCDeskshareManager::handleStartSharingEvent");
JSLog.warn("WebRTCDeskshareManager::handleStartSharingEvent", {});
var onFailure:Function = function(message:String):void {
JSLog.warn(message, {});
usingWebRTC = false;
// send out event to fallback to Java
JSLog.warn("WebRTCDeskshareManager::handleStartSharingEvent - falling back to java", {});
globalDispatcher.dispatchEvent(new UseJavaModeCommand());
return;
};
var onSuccess:Function = function(message:String):void {
JSLog.warn(message, {});
usingWebRTC = true;
startWebRTCDeskshare();
};
canIUseVertoOnThisBrowser(onFailure, onSuccess);
}
public function handleShareWindowCloseEvent():void {
publishWindowManager.handleShareWindowCloseEvent();
sharing = false;
stopWebRTCDeskshare();
}
public function handleViewWindowCloseEvent():void {
LOGGER.debug("Received stop viewing command");
JSLog.warn("WebRTCDeskshareManager::handleViewWindowCloseEvent", {});
viewWindowManager.handleViewWindowCloseEvent();
}
public function handleStreamStartEvent(e:WebRTCViewStreamEvent):void{
// if (!usingWebRTC) { return; } //TODO this was causing issues
if (sharing) return; //TODO must uncomment this for the non-webrtc desktop share
var isPresenter:Boolean = UserManager.getInstance().getConference().amIPresenter;
LOGGER.debug("Received start viewing command when isPresenter==[{0}]",[isPresenter]);
if(isPresenter) {
publishWindowManager.startViewing(e.rtmp, e.videoWidth, e.videoHeight);
} else {
viewWindowManager.startViewing(e.rtmp, e.videoWidth, e.videoHeight);
}
sharing = true; //TODO must uncomment this for the non-webrtc desktop share
}
public function handleUseJavaModeCommand():void {
usingWebRTC = false;
}
}
}

View File

@ -1,86 +0,0 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2015 BigBlueButton Inc. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 3.0 of the License, or (at your option) any later
* version.
*
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.modules.deskshare.managers
{
import com.asfusion.mate.events.Dispatcher;
import flash.events.TimerEvent;
import flash.utils.Timer;
import org.as3commons.logging.api.ILogger;
import org.as3commons.logging.api.getClassLogger;
import org.bigbluebutton.common.IBbbModuleWindow;
import org.bigbluebutton.common.events.CloseWindowEvent;
import org.bigbluebutton.common.events.OpenWindowEvent;
import org.bigbluebutton.modules.deskshare.services.WebRTCDeskshareService;
import org.bigbluebutton.modules.deskshare.view.components.WebRTCDesktopPublishWindow;
public class WebRTCPublishWindowManager {
private static const LOGGER:ILogger = getClassLogger(PublishWindowManager);
private var shareWindow:WebRTCDesktopPublishWindow;
private var globalDispatcher:Dispatcher;
private var service:WebRTCDeskshareService;
private var buttonShownOnToolbar:Boolean = false;
// Timer to auto-publish webcam. We need this timer to delay
// the auto-publishing until after the Viewers's window has loaded
// to receive the publishing events. Otherwise, the user joining next
// won't be able to view the webcam.
private var autoPublishTimer:Timer;
public function WebRTCPublishWindowManager(service:WebRTCDeskshareService) {
LOGGER.debug("PublishWindowManager init");
globalDispatcher = new Dispatcher();
this.service = service;
}
public function stopSharing():void {
if (shareWindow != null) shareWindow.stopSharing();
}
private function autopublishTimerHandler(event:TimerEvent):void {
shareWindow.shareScreen(true);
}
public function handleShareWindowCloseEvent():void {
closeWindow(shareWindow);
}
private function openWindow(window:IBbbModuleWindow):void {
var event:OpenWindowEvent = new OpenWindowEvent(OpenWindowEvent.OPEN_WINDOW_EVENT);
event.window = window;
globalDispatcher.dispatchEvent(event);
}
private function closeWindow(window:IBbbModuleWindow):void {
var event:CloseWindowEvent = new CloseWindowEvent(CloseWindowEvent.CLOSE_WINDOW_EVENT);
event.window = window;
globalDispatcher.dispatchEvent(event);
}
public function startViewing(rtmp:String, videoWidth:Number, videoHeight:Number):void{
shareWindow = new WebRTCDesktopPublishWindow();
shareWindow.visible = true;
openWindow(shareWindow);
shareWindow.startVideo(rtmp, videoWidth, videoHeight);
}
}
}

View File

@ -1,78 +0,0 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2015 BigBlueButton Inc. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 3.0 of the License, or (at your option) any later
* version.
*
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.modules.deskshare.managers
{
import com.asfusion.mate.events.Dispatcher;
import org.as3commons.logging.api.ILogger;
import org.as3commons.logging.api.getClassLogger;
import org.bigbluebutton.common.IBbbModuleWindow;
import org.bigbluebutton.common.events.CloseWindowEvent;
import org.bigbluebutton.common.events.OpenWindowEvent;
import org.bigbluebutton.modules.deskshare.services.WebRTCDeskshareService;
import org.bigbluebutton.modules.deskshare.view.components.WebRTCDesktopPublishWindow;
import org.bigbluebutton.modules.deskshare.view.components.WebRTCDesktopViewWindow;
public class WebRTCViewerWindowManager {
private static const LOGGER:ILogger = getClassLogger(ViewerWindowManager);
private var viewWindow:WebRTCDesktopViewWindow;
private var shareWindow:WebRTCDesktopPublishWindow;
private var service:WebRTCDeskshareService;
private var isViewing:Boolean = false;
private var globalDispatcher:Dispatcher;
public function WebRTCViewerWindowManager(service:WebRTCDeskshareService) {
this.service = service;
globalDispatcher = new Dispatcher();
}
public function stopViewing():void {
if (isViewing) viewWindow.stopViewing();
}
private function openWindow(window:IBbbModuleWindow):void{
var event:OpenWindowEvent = new OpenWindowEvent(OpenWindowEvent.OPEN_WINDOW_EVENT);
event.window = window;
globalDispatcher.dispatchEvent(event);
}
public function handleViewWindowCloseEvent():void {
LOGGER.debug("ViewerWindowManager Received stop viewing command");
closeWindow(viewWindow);
isViewing = false;
}
private function closeWindow(window:IBbbModuleWindow):void {
var event:CloseWindowEvent = new CloseWindowEvent(CloseWindowEvent.CLOSE_WINDOW_EVENT);
event.window = window;
globalDispatcher.dispatchEvent(event);
}
public function startViewing(rtmp:String, videoWidth:Number, videoHeight:Number):void{
LOGGER.debug("ViewerWindowManager::startViewing");
viewWindow = new WebRTCDesktopViewWindow();
viewWindow.startVideo(rtmp, videoWidth, videoHeight);
openWindow(viewWindow);
isViewing = true;
}
}
}

View File

@ -1,103 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
This program is free software; you can redistribute it and/or modify it under the
terms of the GNU Lesser General Public License as published by the Free Software
Foundation; either version 3.0 of the License, or (at your option) any later
version.
BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
-->
<EventMap xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns="http://mate.asfusion.com/">
<mx:Script>
<![CDATA[
import mx.events.FlexEvent;
import org.bigbluebutton.main.events.BBBEvent;
import org.bigbluebutton.main.events.MadePresenterEvent;
import org.bigbluebutton.modules.deskshare.events.ModuleEvent;
import org.bigbluebutton.modules.deskshare.events.ShareEvent;
import org.bigbluebutton.modules.deskshare.events.ShareWindowEvent;
import org.bigbluebutton.modules.deskshare.events.StartedViewingEvent;
import org.bigbluebutton.modules.deskshare.events.StreamEvent;
import org.bigbluebutton.modules.deskshare.events.UseJavaModeCommand;
import org.bigbluebutton.modules.deskshare.events.ViewStreamEvent;
import org.bigbluebutton.modules.deskshare.events.ViewWindowEvent;
import org.bigbluebutton.modules.deskshare.managers.DeskshareManager;
]]>
</mx:Script>
<EventHandlers type="{FlexEvent.PREINITIALIZE}">
<!--
The FlexEvent.PREINITIALIZE event is a good place for creating and initializing managers.
-->
<ObjectBuilder generator="{DeskshareManager}"/>
</EventHandlers>
<EventHandlers type="{ShareEvent.START_SHARING}">
<MethodInvoker generator="{DeskshareManager}" method="handleStartSharingEvent" arguments="{false}"/>
</EventHandlers>
<EventHandlers type="{BBBEvent.START_DESKSHARE}">
<MethodInvoker generator="{DeskshareManager}" method="handleStartSharingEvent" arguments="{true}"/>
</EventHandlers>
<EventHandlers type="{MadePresenterEvent.SWITCH_TO_PRESENTER_MODE}">
<MethodInvoker generator="{DeskshareManager}" method="handleMadePresenterEvent" arguments="{event}"/>
</EventHandlers>
<EventHandlers type="{MadePresenterEvent.SWITCH_TO_VIEWER_MODE}">
<MethodInvoker generator="{DeskshareManager}" method="handleMadeViewerEvent" arguments="{event}"/>
</EventHandlers>
<EventHandlers type="{StreamEvent.START}">
<MethodInvoker generator="{DeskshareManager}" method="handleStreamStartedEvent" arguments="{[event.videoWidth, event.videoHeight]}"/>
</EventHandlers>
<EventHandlers type="{StreamEvent.STOP}" >
<MethodInvoker generator="{DeskshareManager}" method="handleStreamStoppedEvent"/>
</EventHandlers>
<EventHandlers type="{ViewStreamEvent.START}">
<MethodInvoker generator="{DeskshareManager}" method="handleStreamStartEvent" arguments="{[event.videoWidth, event.videoHeight]}"/>
</EventHandlers>
<EventHandlers type="{ShareWindowEvent.CLOSE}">
<MethodInvoker generator="{DeskshareManager}" method="handleShareWindowCloseEvent"/>
</EventHandlers>
<EventHandlers type="{StartedViewingEvent.STARTED_VIEWING_EVENT}">
<MethodInvoker generator="{DeskshareManager}" method="handleStartedViewingEvent" arguments="{event.stream}"/>
</EventHandlers>
<EventHandlers type="{ViewWindowEvent.CLOSE}">
<MethodInvoker generator="{DeskshareManager}" method="handleViewWindowCloseEvent"/>
</EventHandlers>
<EventHandlers type="{UseJavaModeCommand.USE_JAVA_MODE}">
<MethodInvoker generator="{DeskshareManager}" method="handleUseJavaModeCommand"/>
</EventHandlers>
<EventHandlers type="{ModuleEvent.STOP}">
<MethodInvoker generator="{DeskshareManager}" method="handleStopModuleEvent"/>
</EventHandlers>
<EventHandlers type="{ModuleEvent.START}">
<MethodInvoker generator="{DeskshareManager}" method="handleStartModuleEvent" arguments="{event.module}"/>
</EventHandlers>
</EventMap>

View File

@ -1,98 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
Copyright (c) 2015 BigBlueButton Inc. and by respective authors (see below).
This program is free software; you can redistribute it and/or modify it under the
terms of the GNU Lesser General Public License as published by the Free Software
Foundation; either version 3.0 of the License, or (at your option) any later
version.
BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
-->
<EventMap xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns="http://mate.asfusion.com/">
<mx:Script>
<![CDATA[
import mx.events.FlexEvent;
import org.bigbluebutton.main.events.BBBEvent;
import org.bigbluebutton.main.events.MadePresenterEvent;
import org.bigbluebutton.modules.deskshare.events.ModuleEvent;
import org.bigbluebutton.modules.deskshare.events.ShareEvent;
import org.bigbluebutton.modules.deskshare.events.UseJavaModeCommand;
import org.bigbluebutton.modules.deskshare.events.WebRTCShareWindowEvent;
import org.bigbluebutton.modules.deskshare.events.WebRTCStreamEvent;
import org.bigbluebutton.modules.deskshare.events.WebRTCViewStreamEvent;
import org.bigbluebutton.modules.deskshare.events.WebRTCViewWindowEvent;
import org.bigbluebutton.modules.deskshare.managers.WebRTCDeskshareManager;
]]>
</mx:Script>
<EventHandlers type="{FlexEvent.PREINITIALIZE}">
<!--
The FlexEvent.PREINITIALIZE event is a good place for creating and initializing managers.
-->
<ObjectBuilder generator="{WebRTCDeskshareManager}"/>
</EventHandlers>
<EventHandlers type="{ShareEvent.START_SHARING}">
<MethodInvoker generator="{WebRTCDeskshareManager}" method="handleStartSharingEvent" arguments="{false}"/>
</EventHandlers>
<EventHandlers type="{BBBEvent.START_DESKSHARE}">
<MethodInvoker generator="{WebRTCDeskshareManager}" method="handleStartSharingEvent" arguments="{true}"/>
</EventHandlers>
<EventHandlers type="{MadePresenterEvent.SWITCH_TO_PRESENTER_MODE}">
<MethodInvoker generator="{WebRTCDeskshareManager}" method="handleMadePresenterEvent" arguments="{event}"/>
</EventHandlers>
<EventHandlers type="{MadePresenterEvent.SWITCH_TO_VIEWER_MODE}">
<MethodInvoker generator="{WebRTCDeskshareManager}" method="handleMadeViewerEvent" arguments="{event}"/>
</EventHandlers>
<EventHandlers type="{WebRTCStreamEvent.STOP}" >
<MethodInvoker generator="{WebRTCDeskshareManager}" method="handleStreamStoppedEvent"/>
</EventHandlers>
<EventHandlers type="{WebRTCViewStreamEvent.START}">
<MethodInvoker generator="{WebRTCDeskshareManager}" method="handleStreamStartEvent" arguments="{event}"/>
</EventHandlers>
<EventHandlers type="{WebRTCViewStreamEvent.STOP}">
<MethodInvoker generator="{WebRTCDeskshareManager}" method="handleStreamStopEvent" arguments="{event}"/>
</EventHandlers>
<EventHandlers type="{WebRTCShareWindowEvent.CLOSE}">
<MethodInvoker generator="{WebRTCDeskshareManager}" method="handleShareWindowCloseEvent"/>
</EventHandlers>
<EventHandlers type="{WebRTCViewWindowEvent.CLOSE}">
<MethodInvoker generator="{WebRTCDeskshareManager}" method="handleViewWindowCloseEvent"/>
</EventHandlers>
<EventHandlers type="{UseJavaModeCommand.USE_JAVA_MODE}">
<MethodInvoker generator="{WebRTCDeskshareManager}" method="handleUseJavaModeCommand"/>
</EventHandlers>
<EventHandlers type="{ModuleEvent.STOP}">
<MethodInvoker generator="{WebRTCDeskshareManager}" method="handleStopModuleEvent"/>
</EventHandlers>
<EventHandlers type="{ModuleEvent.START}">
<MethodInvoker generator="{WebRTCDeskshareManager}" method="handleStartModuleEvent" arguments="{event.module}"/>
</EventHandlers>
</EventMap>

View File

@ -1,90 +0,0 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 3.0 of the License, or (at your option) any later
* version.
*
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.modules.deskshare.model
{
import flash.external.ExternalInterface;
import org.bigbluebutton.core.BBB;
public class DeskshareOptions
{
[Bindable] public var showButton:Boolean = true;
[Bindable] public var autoStart:Boolean = false;
[Bindable] public var autoFullScreen:Boolean = false;
public var useTLS:Boolean = false;
[Bindable] public var baseTabIndex:int;
public var publishURI:String;
[Bindable] public var useWebRTCIfAvailable:Boolean = true;
[Bindable] public var chromeExtensionKey:String = null;
[Bindable] public var vertoPort:String = null;
[Bindable] public var hostName:String = null;
[Bindable] public var login:String = null;
[Bindable] public var password:String = null;
public function parseOptions():void {
var vxml:XML = BBB.getConfigForModule("DeskShareModule");
if (vxml != null) {
publishURI = "";
if (vxml.@publishURI != undefined){
publishURI = vxml.@publishURI.toString();
}
if (vxml.@autoStart != undefined) {
autoStart = (vxml.@autoStart.toString().toUpperCase() == "TRUE") ? true : false;
}
if (vxml.@useTLS != undefined){
useTLS = (vxml.@useTLS.toString().toUpperCase() == "TRUE") ? true : false;
}
if (vxml.@autoFullScreen != undefined){
autoFullScreen = (vxml.@autoFullScreen.toString().toUpperCase() == "TRUE") ? true : false;
}
if (vxml.@baseTabIndex != undefined) {
baseTabIndex = vxml.@baseTabIndex;
}
else{
baseTabIndex = 201;
}
if (vxml.@showButton != undefined){
showButton = (vxml.@showButton.toString().toUpperCase() == "TRUE") ? true : false;
// If we are using Puffin browser
if (ExternalInterface.call("determineBrowser")[0] == "Puffin") {
showButton = false;
}
}
if (vxml.@useWebRTCIfAvailable != undefined) {
useWebRTCIfAvailable = (vxml.@useWebRTCIfAvailable.toString().toUpperCase() == "TRUE");
}
if (vxml.@chromeExtensionKey != undefined) {
chromeExtensionKey = vxml.@chromeExtensionKey.toString();
}
if (vxml.@vertoPort != undefined) {
vertoPort = vxml.@vertoPort.toString();
}
if (vxml.@hostName != undefined) {
hostName = vxml.@hostName.toString();
}
if (vxml.@login != undefined) {
login = vxml.@login.toString();
}
if (vxml.@password != undefined) {
password = vxml.@password.toString();
}
}
}
}
}

View File

@ -1,89 +0,0 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 3.0 of the License, or (at your option) any later
* version.
*
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.modules.deskshare.services
{
import com.asfusion.mate.events.Dispatcher;
import flash.net.NetConnection;
import org.as3commons.logging.api.ILogger;
import org.as3commons.logging.api.getClassLogger;
import org.bigbluebutton.modules.deskshare.services.red5.Connection;
/**
* The DeskShareProxy communicates with the Red5 deskShare server application
* @author Snap
*
*/
public class DeskshareService
{
private static const LOGGER:ILogger = getClassLogger(DeskshareService);
private var conn:Connection;
private var module:DeskShareModule;
private var dispatcher:Dispatcher;
private var uri:String;
private var room:String;
public function DeskshareService() {
this.dispatcher = new Dispatcher();
}
public function handleStartModuleEvent(module:DeskShareModule):void {
LOGGER.debug("Deskshare Module starting");
this.module = module;
connect(module.uri, module.getRoom());
}
public function connect(uri:String, room:String):void {
this.uri = uri;
this.room = room;
LOGGER.debug("Deskshare Service connecting to {0}", [uri]);
conn = new Connection(room);
conn.setURI(uri);
conn.connect();
}
public function getConnection():NetConnection{
return conn.getConnection();
}
public function disconnect():void{
conn.disconnect();
}
public function sendStartViewingNotification(captureWidth:Number, captureHeight:Number):void{
conn.sendStartViewingNotification(captureWidth, captureHeight);
}
public function sendStartedViewingNotification(stream:String):void{
conn.sendStartedViewingNotification(stream);
}
public function stopSharingDesktop(meetingId: String, stream: String):void {
conn.stopSharingDesktop(meetingId, stream);
}
}
}

View File

@ -1,74 +0,0 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2015 BigBlueButton Inc. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 3.0 of the License, or (at your option) any later
* version.
*
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.modules.deskshare.services
{
import com.asfusion.mate.events.Dispatcher;
import flash.net.NetConnection;
import org.as3commons.logging.api.ILogger;
import org.as3commons.logging.api.getClassLogger;
import org.bigbluebutton.modules.deskshare.services.red5.WebRTCConnection;
/**
* The DeskShareProxy communicates with the Red5 deskShare server application
* @author Snap
*
*/
public class WebRTCDeskshareService
{
private static const LOGGER:ILogger = getClassLogger(DeskshareService);
private var conn:WebRTCConnection;
private var module:DeskShareModule;
private var dispatcher:Dispatcher;
private var uri:String;
private var room:String;
public function WebRTCDeskshareService() {
this.dispatcher = new Dispatcher();
}
public function handleStartModuleEvent(module:DeskShareModule):void {
LOGGER.debug("Deskshare Module starting");
this.module = module;
connect(module.uri, module.getRoom());
}
public function connect(uri:String, room:String):void {
this.uri = uri;
this.room = room;
LOGGER.debug("Deskshare Service connecting to {0}", [uri]);
conn = new WebRTCConnection(room); //to red5 deskshare
conn.setURI(uri);
conn.connect();
}
public function getConnection():NetConnection{
return conn.getConnection();
}
public function disconnect():void{
conn.disconnect();
}
}
}

View File

@ -1,411 +0,0 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 3.0 of the License, or (at your option) any later
* version.
*
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.modules.deskshare.services.red5
{
import com.asfusion.mate.events.Dispatcher;
import flash.events.AsyncErrorEvent;
import flash.events.NetStatusEvent;
import flash.events.SecurityErrorEvent;
import flash.events.TimerEvent;
import flash.net.NetConnection;
import flash.net.ObjectEncoding;
import flash.net.Responder;
import flash.net.SharedObject;
import flash.utils.Timer;
import mx.utils.ObjectUtil;
import org.as3commons.logging.api.ILogger;
import org.as3commons.logging.api.getClassLogger;
import org.bigbluebutton.core.UsersUtil;
import org.bigbluebutton.core.managers.ReconnectionManager;
import org.bigbluebutton.main.events.BBBEvent;
import org.bigbluebutton.modules.deskshare.events.AppletStartedEvent;
import org.bigbluebutton.modules.deskshare.events.CursorEvent;
import org.bigbluebutton.modules.deskshare.events.ViewStreamEvent;
public class Connection {
private static const LOGGER:ILogger = getClassLogger(Connection);
private var nc:NetConnection;
private var uri:String;
private var retryTimer:Timer = null;
private var retryCount:int = 0;
private const MAX_RETRIES:int = 5;
private var deskSO:SharedObject;
private var responder:Responder;
private var width:Number;
private var height:Number;
private var room:String;
private var logoutOnUserCommand:Boolean = false;
private var reconnecting:Boolean = false;
private var wasPresenterBeforeDisconnect:Boolean = false;
private var dispatcher:Dispatcher = new Dispatcher();
public function Connection(room:String) {
this.room = room;
responder = new Responder(
function(result:Object):void {
if (result != null && (result.publishing as Boolean)){
width = result.width as Number;
height = result.height as Number;
LOGGER.debug("Desk Share stream is streaming [{0},{1}]", [width, height]);
var event:ViewStreamEvent = new ViewStreamEvent(ViewStreamEvent.START);
event.videoWidth = width;
event.videoHeight = height;
dispatcher.dispatchEvent(event);
} else {
LOGGER.debug("No deskshare stream being published");
var connEvent:ConnectionEvent = new ConnectionEvent();
connEvent.status = ConnectionEvent.NO_DESKSHARE_STREAM;
dispatcher.dispatchEvent(connEvent);
}
},
function(status:Object):void{
var checkFailedEvent:ConnectionEvent = new ConnectionEvent();
checkFailedEvent.status = ConnectionEvent.FAIL_CHECK_FOR_DESKSHARE_STREAM;
dispatcher.dispatchEvent(checkFailedEvent);
LOGGER.debug("Error while trying to call remote mathod on server");
}
);
}
public function connect(retry:Boolean = false):void {
nc = new NetConnection();
nc.proxyType = "best";
nc.objectEncoding = ObjectEncoding.AMF0;
nc.client = this;
nc.addEventListener(AsyncErrorEvent.ASYNC_ERROR, debugAsyncErrorHandler);
nc.addEventListener(NetStatusEvent.NET_STATUS, debugNetStatusHandler);
nc.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler);
nc.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
if (getURI().length == 0){
LOGGER.error("please provide a valid URI connection string. URI Connection String missing");
return;
} else if (nc.connected){
LOGGER.error("You are already connected to {0}", [getURI()]);
return;
}
LOGGER.debug("Trying to connect to [{0}] retry=[{1}]", [getURI(), retry]);
if (! (retryCount > 0)) {
var ce:ConnectionEvent = new ConnectionEvent();
ce.status = ConnectionEvent.CONNECTING;
dispatcher.dispatchEvent(ce);
}
nc.connect(getURI(), UsersUtil.getInternalMeetingID());
}
private function connectTimeoutHandler(e:TimerEvent):void {
LOGGER.debug("Connection attempt to [{0}] timedout. Retrying.", [getURI()]);
retryTimer.stop();
retryTimer = null;
nc.close();
nc = null;
var ce:ConnectionEvent = new ConnectionEvent();;
retryCount++;
if (retryCount < MAX_RETRIES) {
ce.status = ConnectionEvent.CONNECTING_RETRY;
ce.retryAttempts = retryCount;
dispatcher.dispatchEvent(ce);
connect(false);
} else {
ce.status = ConnectionEvent.CONNECTING_MAX_RETRY;
dispatcher.dispatchEvent(ce);
}
}
public function close():void{
nc.close();
}
public function setURI(p_URI:String):void{
uri = p_URI;
}
public function getURI():String{
return uri;
}
public function onBWCheck(... rest):Number {
return 0;
}
public function onBWDone(... rest):void {
var p_bw:Number;
if (rest.length > 0) p_bw = rest[0];
// your application should do something here
// when the bandwidth check is complete
LOGGER.debug("bandwidth = {0} Kbps.", [p_bw]);
}
private function netStatusHandler(event:NetStatusEvent):void {
LOGGER.debug("Connected to [" + getURI() + "]. [" + event.info.code + "]");
if (retryTimer) {
retryCount = 0;
LOGGER.debug("Cancelling retry timer.");
retryTimer.stop();
retryTimer = null;
}
var ce:ConnectionEvent = new ConnectionEvent();
switch(event.info.code){
case "NetConnection.Connect.Failed":
if (reconnecting) {
var attemptFailedEvent:BBBEvent = new BBBEvent(BBBEvent.RECONNECT_CONNECTION_ATTEMPT_FAILED_EVENT);
attemptFailedEvent.payload.type = ReconnectionManager.DESKSHARE_CONNECTION;
dispatcher.dispatchEvent(attemptFailedEvent);
}
ce.status = ConnectionEvent.FAILED;
dispatcher.dispatchEvent(ce);
break;
case "NetConnection.Connect.Success":
ce.status = ConnectionEvent.SUCCESS;
if (reconnecting) {
reconnecting = false;
if (wasPresenterBeforeDisconnect) {
wasPresenterBeforeDisconnect = false;
stopSharingDesktop(room, room)
}
var attemptSucceeded:BBBEvent = new BBBEvent(BBBEvent.RECONNECT_CONNECTION_ATTEMPT_SUCCEEDED_EVENT);
attemptSucceeded.payload.type = ReconnectionManager.DESKSHARE_CONNECTION;
dispatcher.dispatchEvent(attemptSucceeded);
}
dispatcher.dispatchEvent(ce);
connectionSuccessHandler();
break;
case "NetConnection.Connect.Rejected":
ce.status = ConnectionEvent.REJECTED;
dispatcher.dispatchEvent(ce);
break;
case "NetConnection.Connect.Closed":
LOGGER.debug("Deskshare connection closed.");
ce.status = ConnectionEvent.CLOSED;
if (UsersUtil.amIPresenter()) {
// Let's keep our presenter status before disconnected. We can't
// tell the other user's to stop desktop sharing as our connection is broken. (ralam july 24, 2015)
wasPresenterBeforeDisconnect = true;
} else {
stopViewing();
}
if (!logoutOnUserCommand) {
reconnecting = true;
var disconnectedEvent:BBBEvent = new BBBEvent(BBBEvent.RECONNECT_DISCONNECTED_EVENT);
disconnectedEvent.payload.type = ReconnectionManager.DESKSHARE_CONNECTION;
disconnectedEvent.payload.callback = connect;
disconnectedEvent.payload.callbackParameters = [];
dispatcher.dispatchEvent(disconnectedEvent);
}
break;
case "NetConnection.Connect.InvalidApp":
ce.status = ConnectionEvent.INVALIDAPP;
dispatcher.dispatchEvent(ce);
break;
case "NetConnection.Connect.AppShutdown":
ce.status = ConnectionEvent.APPSHUTDOWN;
dispatcher.dispatchEvent(ce);
break;
case "NetConnection.Connect.NetworkChange":
LOGGER.info("Detected network change. User might be on a wireless and temporarily dropped connection. Doing nothing. Just making a note.");
break;
default :
// I dispatch DISCONNECTED incase someone just simply wants to know if we're not connected'
// rather than having to subscribe to the events individually
ce.status = ConnectionEvent.DISCONNECTED;
dispatcher.dispatchEvent(ce);
break;
}
}
private function securityErrorHandler(event:SecurityErrorEvent):void{
var ce:ConnectionEvent = new ConnectionEvent();
ce.status = ConnectionEvent.SECURITYERROR;
dispatcher.dispatchEvent(ce);
}
public function mouseLocationCallback(x:Number, y:Number):void {
var event:CursorEvent = new CursorEvent(CursorEvent.UPDATE_CURSOR_LOC_EVENT);
event.x = x;
event.y = y;
dispatcher.dispatchEvent(event);
}
/**
* Check if anybody is publishing the stream for this room
* This method is useful for clients which have joined a room where somebody is already publishing
*
*/
private function checkIfStreamIsPublishing(room: String):void{
LOGGER.debug("checking if desk share stream is publishing");
var event:ConnectionEvent = new ConnectionEvent();
event.status = ConnectionEvent.CHECK_FOR_DESKSHARE_STREAM;
dispatcher.dispatchEvent(event);
nc.call("deskshare.checkIfStreamIsPublishing", responder, room);
}
public function disconnect():void{
logoutOnUserCommand = true;
if (nc != null) nc.close();
}
public function connectionSuccessHandler():void{
LOGGER.debug("Successully connection to {0}", [uri]);
var deskSOName:String = room + "-deskSO";
deskSO = SharedObject.getRemote(deskSOName, uri, false);
deskSO.client = this;
deskSO.addEventListener(AsyncErrorEvent.ASYNC_ERROR, debugAsyncErrorHandler);
deskSO.addEventListener(NetStatusEvent.NET_STATUS, debugNetStatusHandler);
deskSO.connect(nc);
checkIfStreamIsPublishing(room);
}
private function debugNetStatusHandler(e:NetStatusEvent):void {
LOGGER.debug("netStatusHandler target={0} info={1}", [e.target, ObjectUtil.toString(e.info)]);
}
private function debugAsyncErrorHandler(e:AsyncErrorEvent):void {
LOGGER.debug("asyncErrorHandler target={0} info={1}", [e.target, e.text]);
}
public function getConnection():NetConnection{
return nc;
}
public function connectionFailedHandler(e:ConnectionEvent):void{
LOGGER.error("connection failed to {0} with message {1}", [uri, e.toString()]);
}
public function connectionRejectedHandler(e:ConnectionEvent):void{
LOGGER.error("connection rejected to {0} with message {1}", [uri, e.toString()]);
}
/**
* Invoked on the server once the clients' applet has started sharing and the server has started a video stream
*
*/
public function appletStarted(videoWidth:Number, videoHeight:Number):void{
LOGGER.debug("Got applet started");
if (nc != null && nc.connected) {
var event:AppletStartedEvent = new AppletStartedEvent();
event.videoWidth = videoWidth;
event.videoHeight = videoHeight;
dispatcher.dispatchEvent(event);
}
}
/**
* Call this method to send out a room-wide notification to start viewing the stream
*
*/
public function sendStartViewingNotification(captureWidth:Number, captureHeight:Number):void{
try{
deskSO.send("startViewing", captureWidth, captureHeight);
} catch(e:Error){
LOGGER.error("error while trying to send start viewing notification");
}
}
public function sendStartedViewingNotification(stream:String):void{
LOGGER.debug("Sending start viewing to server");
nc.call("deskshare.startedToViewStream", null, stream);
}
public function stopSharingDesktop(meetingId: String, stream: String):void {
nc.call("deskshare.stopSharingDesktop", null, meetingId);
}
/**
* Called by the server when a notification is received to start viewing the broadcast stream .
* This method is called on successful execution of sendStartViewingNotification()
*
*/
public function startViewing(videoWidth:Number, videoHeight:Number):void{
LOGGER.debug("startViewing invoked by server");
var event:ViewStreamEvent = new ViewStreamEvent(ViewStreamEvent.START);
event.videoWidth = videoWidth;
event.videoHeight = videoHeight;
dispatcher.dispatchEvent(event);
}
/**
* Sends a notification through the server to all the participants in the room to stop viewing the stream
*
*/
public function sendStopViewingNotification():void{
LOGGER.debug("Sending stop viewing notification to other clients.");
try{
deskSO.send("stopViewing");
} catch(e:Error){
LOGGER.debug("could not send stop viewing notification");
}
}
/**
* Called by the server to notify clients that the deskshare stream has stooped.
*/
public function deskshareStreamStopped():void {
stopViewing();
}
/**
* Sends a notification to the module to stop viewing the stream
* This method is called on successful execution of sendStopViewingNotification()
*
*/
public function stopViewing():void{
LOGGER.debug("Received dekskshareStreamStopped");
dispatcher.dispatchEvent(new ViewStreamEvent(ViewStreamEvent.STOP));
}
}
}

View File

@ -1,50 +0,0 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 3.0 of the License, or (at your option) any later
* version.
*
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.modules.deskshare.services.red5
{
import flash.events.Event;
public class ConnectionEvent extends Event {
public static const DESKSHARE_CONNECTION_EVENT:String = "deskshare connection event";
public static const SUCCESS:String = "connection success";
public static const FAILED:String = "connection failed";
public static const CLOSED:String = "connection closed";
public static const REJECTED:String = "connection rejected";
public static const INVALIDAPP:String = "connection invalidApp";
public static const APPSHUTDOWN:String = "connection appShutdown";
public static const SECURITYERROR:String = "connection securityError";
public static const DISCONNECTED:String = "connection disconnected";
public static const CONNECTING:String = "connection connecting";
public static const CONNECTING_RETRY:String = "connection retry";
public static const CONNECTING_MAX_RETRY:String = "connection max retry";
public static const CHECK_FOR_DESKSHARE_STREAM:String = "connection check deskshare publishing";
public static const NO_DESKSHARE_STREAM:String = "connection deskshare publishing";
public static const FAIL_CHECK_FOR_DESKSHARE_STREAM:String = "connection failed check deskshare publishing";
public var status:String = "";
public var retryAttempts:int = 0;
public function ConnectionEvent():void {
super(DESKSHARE_CONNECTION_EVENT, true, false);
}
}
}

View File

@ -1,322 +0,0 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2015 BigBlueButton Inc. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 3.0 of the License, or (at your option) any later
* version.
*
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.modules.deskshare.services.red5
{
import com.asfusion.mate.events.Dispatcher;
import flash.events.AsyncErrorEvent;
import flash.events.NetStatusEvent;
import flash.events.SecurityErrorEvent;
import flash.events.TimerEvent;
import flash.net.NetConnection;
import flash.net.ObjectEncoding;
import flash.net.Responder;
import flash.utils.Timer;
import mx.utils.ObjectUtil;
import org.as3commons.logging.api.ILogger;
import org.as3commons.logging.api.getClassLogger;
import org.bigbluebutton.core.BBB;
import org.bigbluebutton.core.UsersUtil;
import org.bigbluebutton.core.managers.ReconnectionManager;
import org.bigbluebutton.main.events.BBBEvent;
import org.bigbluebutton.modules.deskshare.events.WebRTCViewStreamEvent;
public class WebRTCConnection {
private static const LOGGER:ILogger = getClassLogger(Connection);
private var nc:NetConnection;
private var uri:String;
private var retryTimer:Timer = null;
private var retryCount:int = 0;
private const MAX_RETRIES:int = 5;
private var responder:Responder;
private var width:Number;
private var height:Number;
private var room:String;
private var logoutOnUserCommand:Boolean = false;
private var reconnecting:Boolean = false;
private var wasPresenterBeforeDisconnect:Boolean = false;
private var dispatcher:Dispatcher = new Dispatcher();
public function WebRTCConnection(room:String) {
this.room = room;
responder = new Responder(
function(result:Object):void {
if (result != null && (result.publishing as Boolean)){
width = result.width as Number;
height = result.height as Number;
LOGGER.debug("Desk Share stream is streaming [{0},{1}]", [width, height]);
var event:WebRTCViewStreamEvent = new WebRTCViewStreamEvent(WebRTCViewStreamEvent.START);
event.videoWidth = width;
event.videoHeight = height;
dispatcher.dispatchEvent(event); //TODO why?
} else {
LOGGER.debug("No deskshare stream being published");
var connEvent:ConnectionEvent = new ConnectionEvent();
connEvent.status = ConnectionEvent.NO_DESKSHARE_STREAM;
dispatcher.dispatchEvent(connEvent); //TODO why?
}
},
function(status:Object):void{
var checkFailedEvent:ConnectionEvent = new ConnectionEvent();
checkFailedEvent.status = ConnectionEvent.FAIL_CHECK_FOR_DESKSHARE_STREAM;
dispatcher.dispatchEvent(checkFailedEvent);
LOGGER.debug("Error while trying to call remote mathod on server");
}
);
}
public function connect(retry:Boolean = false):void {
nc = new NetConnection();
nc.proxyType = "best";
nc.objectEncoding = ObjectEncoding.AMF0;
nc.client = this;
nc.addEventListener(AsyncErrorEvent.ASYNC_ERROR, debugAsyncErrorHandler);
nc.addEventListener(NetStatusEvent.NET_STATUS, debugNetStatusHandler);
nc.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler);
nc.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
if (getURI().length == 0){
LOGGER.error("please provide a valid URI connection string. URI Connection String missing");
return;
} else if (nc.connected){
LOGGER.error("You are already connected to {0}", [getURI()]);
return;
}
LOGGER.debug("Trying to connect to [{0}] retry=[{1}]", [getURI(), retry]);
if (! (retryCount > 0)) {
var ce:ConnectionEvent = new ConnectionEvent();
ce.status = ConnectionEvent.CONNECTING;
dispatcher.dispatchEvent(ce);
}
nc.connect(getURI(), UsersUtil.getInternalMeetingID());
}
private function connectTimeoutHandler(e:TimerEvent):void {
LOGGER.debug("Connection attempt to [{0}] timedout. Retrying.", [getURI()]);
retryTimer.stop();
retryTimer = null;
nc.close();
nc = null;
var ce:ConnectionEvent = new ConnectionEvent();;
retryCount++;
if (retryCount < MAX_RETRIES) {
ce.status = ConnectionEvent.CONNECTING_RETRY;
ce.retryAttempts = retryCount;
dispatcher.dispatchEvent(ce);
connect(false);
} else {
ce.status = ConnectionEvent.CONNECTING_MAX_RETRY;
dispatcher.dispatchEvent(ce);
}
}
public function close():void{
nc.close();
}
public function setURI(p_URI:String):void{
uri = p_URI;
}
public function getURI():String{
return uri;
}
public function onBWCheck(... rest):Number {
return 0;
}
public function onBWDone(... rest):void {
var p_bw:Number;
if (rest.length > 0) p_bw = rest[0];
// your application should do something here
// when the bandwidth check is complete
LOGGER.debug("bandwidth = {0} Kbps.", [p_bw]);
}
private function netStatusHandler(event:NetStatusEvent):void {
LOGGER.debug("Connected to [" + getURI() + "]. [" + event.info.code + "]");
if (retryTimer) {
retryCount = 0;
LOGGER.debug("Cancelling retry timer.");
retryTimer.stop();
retryTimer = null;
}
var ce:ConnectionEvent = new ConnectionEvent();
switch(event.info.code){
case "NetConnection.Connect.Failed":
if (reconnecting) {
var attemptFailedEvent:BBBEvent = new BBBEvent(BBBEvent.RECONNECT_CONNECTION_ATTEMPT_FAILED_EVENT);
attemptFailedEvent.payload.type = ReconnectionManager.DESKSHARE_CONNECTION;
dispatcher.dispatchEvent(attemptFailedEvent);
}
ce.status = ConnectionEvent.FAILED;
dispatcher.dispatchEvent(ce);
break;
case "NetConnection.Connect.Success":
ce.status = ConnectionEvent.SUCCESS;
if (reconnecting) {
reconnecting = false;
if (wasPresenterBeforeDisconnect) {
wasPresenterBeforeDisconnect = false;
// stopSharingDesktop(room, room) //TODO
}
var attemptSucceeded:BBBEvent = new BBBEvent(BBBEvent.RECONNECT_CONNECTION_ATTEMPT_SUCCEEDED_EVENT);
attemptSucceeded.payload.type = ReconnectionManager.DESKSHARE_CONNECTION;
dispatcher.dispatchEvent(attemptSucceeded);
}
// request desktop sharing info (as a late joiner)
LOGGER.debug("Sending [desktopSharing.requestDeskShareInfo] to server.");
var _nc:ConnectionManager = BBB.initConnectionManager();
_nc.sendMessage("desktopSharing.requestDeskShareInfo",
function(result:String):void { // On successful result
LOGGER.debug(result);
},
function(status:String):void { // status - On error occurred
LOGGER.error(status);
}
);
dispatcher.dispatchEvent(ce);
break;
case "NetConnection.Connect.Rejected":
ce.status = ConnectionEvent.REJECTED;
dispatcher.dispatchEvent(ce);
break;
case "NetConnection.Connect.Closed":
LOGGER.debug("Deskshare connection closed.");
ce.status = ConnectionEvent.CLOSED;
if (UsersUtil.amIPresenter()) {
// Let's keep our presenter status before disconnected. We can't
// tell the other user's to stop desktop sharing as our connection is broken. (ralam july 24, 2015)
wasPresenterBeforeDisconnect = true;
} else {
// stopViewing(); //TODO
}
if (!logoutOnUserCommand) {
reconnecting = true;
var disconnectedEvent:BBBEvent = new BBBEvent(BBBEvent.RECONNECT_DISCONNECTED_EVENT);
disconnectedEvent.payload.type = ReconnectionManager.DESKSHARE_CONNECTION;
disconnectedEvent.payload.callback = connect;
disconnectedEvent.payload.callbackParameters = [];
dispatcher.dispatchEvent(disconnectedEvent);
}
break;
case "NetConnection.Connect.InvalidApp":
ce.status = ConnectionEvent.INVALIDAPP;
dispatcher.dispatchEvent(ce);
break;
case "NetConnection.Connect.AppShutdown":
ce.status = ConnectionEvent.APPSHUTDOWN;
dispatcher.dispatchEvent(ce);
break;
case "NetConnection.Connect.NetworkChange":
LOGGER.info("Detected network change. User might be on a wireless and temporarily dropped connection. Doing nothing. Just making a note.");
break;
default :
// I dispatch DISCONNECTED incase someone just simply wants to know if we're not connected'
// rather than having to subscribe to the events individually
ce.status = ConnectionEvent.DISCONNECTED;
dispatcher.dispatchEvent(ce);
break;
}
}
private function securityErrorHandler(event:SecurityErrorEvent):void{
var ce:ConnectionEvent = new ConnectionEvent();
ce.status = ConnectionEvent.SECURITYERROR;
dispatcher.dispatchEvent(ce);
}
/**
* Check if anybody is publishing the stream for this room
* This method is useful for clients which have joined a room where somebody is already publishing
*
*/
private function checkIfStreamIsPublishing(room: String):void{
LOGGER.debug("checking if desk share stream is publishing");
var event:ConnectionEvent = new ConnectionEvent();
event.status = ConnectionEvent.CHECK_FOR_DESKSHARE_STREAM;
dispatcher.dispatchEvent(event); // TODO anton send to akka-bbb-apps
nc.call("deskshare.checkIfStreamIsPublishing", responder, room);
}
public function disconnect():void{
logoutOnUserCommand = true;
if (nc != null) nc.close();
}
public function connectionSuccessHandler():void{
LOGGER.debug("Successully connection to {0}", [uri]);
checkIfStreamIsPublishing(room);
}
private function debugNetStatusHandler(e:NetStatusEvent):void {
LOGGER.debug("netStatusHandler target={0} info={1}", [e.target, ObjectUtil.toString(e.info)]);
}
private function debugAsyncErrorHandler(e:AsyncErrorEvent):void {
LOGGER.debug("asyncErrorHandler target={0} info={1}", [e.target, e.text]);
}
public function getConnection():NetConnection{
return nc;
}
public function connectionFailedHandler(e:ConnectionEvent):void{
LOGGER.error("connection failed to {0} with message {1}", [uri, e.toString()]);
}
public function connectionRejectedHandler(e:ConnectionEvent):void{
LOGGER.error("connection rejected to {0} with message {1}", [uri, e.toString()]);
}
}
}

View File

@ -1,49 +0,0 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2015 BigBlueButton Inc. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 3.0 of the License, or (at your option) any later
* version.
*
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.modules.deskshare.services.red5
{
import flash.events.Event;
public class WebRTCConnectionEvent extends Event {
public static const DESKSHARE_CONNECTION_EVENT:String = "webrtcDeskshare connection event";
public static const SUCCESS:String = "connection success";
public static const FAILED:String = "connection failed";
public static const CLOSED:String = "connection closed";
public static const REJECTED:String = "connection rejected";
public static const INVALIDAPP:String = "connection invalidApp";
public static const APPSHUTDOWN:String = "connection appShutdown";
public static const SECURITYERROR:String = "connection securityError";
public static const DISCONNECTED:String = "connection disconnected";
public static const CONNECTING:String = "connection connecting";
public static const CONNECTING_RETRY:String = "connection retry";
public static const CONNECTING_MAX_RETRY:String = "connection max retry";
public static const CHECK_FOR_DESKSHARE_STREAM:String = "connection check webrtcDeskshare publishing";
public static const NO_DESKSHARE_STREAM:String = "connection webrtcDeskshare publishing";
public static const FAIL_CHECK_FOR_DESKSHARE_STREAM:String = "connection failed check webrtcDeskshare publishing";
public var status:String = "";
public var retryAttempts:int = 0;
public function WebRTCConnectionEvent():void {
super(DESKSHARE_CONNECTION_EVENT, true, false);
}
}
}

View File

@ -1,62 +0,0 @@
/**
* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
*
* Copyright (c) 2016 BigBlueButton Inc. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 3.0 of the License, or (at your option) any later
* version.
*
* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.modules.deskshare.utils
{
import flash.external.ExternalInterface;
import org.bigbluebutton.core.BBB;
import flash.system.Capabilities;
import org.as3commons.logging.api.getClassLogger;
import org.as3commons.logging.api.ILogger;
public class BrowserCheck {
private static const LOGGER:ILogger = getClassLogger(BrowserCheck);
public static function isChrome42OrHigher():Boolean {
var browser:Array = ExternalInterface.call("determineBrowser");
return ((browser[0] == "Chrome") && (parseInt(browser[1]) >= 42));
}
public static function isUsingLessThanChrome38OnMac():Boolean {
var browser:Array = ExternalInterface.call("determineBrowser");
return ((browser[0] == "Chrome") && (parseInt(browser[1]) <= 38) && (Capabilities.os.indexOf("Mac") >= 0));
}
public static function isWebRTCSupported():Boolean {
LOGGER.debug("isWebRTCSupported - ExternalInterface.available=[{0}], isWebRTCAvailable=[{1}]", [ExternalInterface.available, ExternalInterface.call("isWebRTCAvailable")]);
return (ExternalInterface.available && ExternalInterface.call("isWebRTCAvailable"));
}
public static function isUsingEdgePluginUnsupported():Boolean {
var browser:Array = ExternalInterface.call("determineBrowser");
/* Currently no browser version of Edge supports plugins */
return browser[0] == "Edge";
}
public static function isChrome():Boolean {
var browser:Array = ExternalInterface.call("determineBrowser");
return browser[0] == "Chrome";
}
public static function isFirefox():Boolean {
var browser:Array = ExternalInterface.call("determineBrowser");
return browser[0] == "Firefox";
}
}
}

View File

@ -1,63 +0,0 @@
/**
* WebMeeting open source conferencing system - http://www.speakserve.org/
*
* Copyright (c) 2016 SpeakServe Ltd. and by respective authors (see below).
*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 3.0 of the License, or (at your option) any later
* version.
*
* WebMeeting is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with WebMeeting; if not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bigbluebutton.modules.deskshare.utils
{
import com.asfusion.mate.events.Dispatcher;
import flash.external.ExternalInterface;
import flash.utils.setTimeout;
import org.bigbluebutton.core.BBB;
import org.bigbluebutton.main.events.ClientStatusEvent;
import org.bigbluebutton.util.i18n.ResourceUtil;
import org.bigbluebutton.modules.deskshare.utils.BrowserCheck;
public class JavaCheck {
public static function checkJava():String {
var dispatcher : Dispatcher = new Dispatcher();
var java_version:String = "1.7.0_51";
var xml:XML = BBB.getConfigManager().config.browserVersions;
if (xml.@java != undefined) {
java_version = xml.@java.toString();
}
var isJavaOk: Object = checkJavaVersion(java_version);
if (isJavaOk.result == "JAVA_OK") {
// Java success
return null;
} else if (isJavaOk.result == "JAVA_NOT_INSTALLED") {
if (!BrowserCheck.isChrome42OrHigher()) {
dispatcher.dispatchEvent(new ClientStatusEvent(ClientStatusEvent.FAIL_MESSAGE_EVENT, ResourceUtil.getInstance().getString("bbb.clientstatus.java.title"), ResourceUtil.getInstance().getString("bbb.clientstatus.java.notinstalled")));
}
return ResourceUtil.getInstance().getString("bbb.clientstatus.java.notinstalled");
} else if (isJavaOk.result == "JAVA_OLDER") {
dispatcher.dispatchEvent(new ClientStatusEvent(ClientStatusEvent.FAIL_MESSAGE_EVENT, ResourceUtil.getInstance().getString("bbb.clientstatus.java.title"), ResourceUtil.getInstance().getString("bbb.clientstatus.java.oldversion")));
return ResourceUtil.getInstance().getString("bbb.clientstatus.java.oldversion");
} else {
dispatcher.dispatchEvent(new ClientStatusEvent(ClientStatusEvent.FAIL_MESSAGE_EVENT, ResourceUtil.getInstance().getString("bbb.clientstatus.java.title"), ResourceUtil.getInstance().getString("bbb.clientstatus.java.notdetected")));
return ResourceUtil.getInstance().getString("bbb.clientstatus.java.notdetected");
}
}
private static function checkJavaVersion(minVersion: String):Object {
return ExternalInterface.call("checkJavaVersion", minVersion);
}
}
}

Some files were not shown because too many files have changed in this diff Show More