diff --git a/bigbluebutton-apps/src/main/java/org/bigbluebutton/core/api/IBigBlueButtonInGW.java b/bigbluebutton-apps/src/main/java/org/bigbluebutton/core/api/IBigBlueButtonInGW.java index 2bae9fd967..6c5983dd6e 100755 --- a/bigbluebutton-apps/src/main/java/org/bigbluebutton/core/api/IBigBlueButtonInGW.java +++ b/bigbluebutton-apps/src/main/java/org/bigbluebutton/core/api/IBigBlueButtonInGW.java @@ -1,18 +1,28 @@ package org.bigbluebutton.core.api; +import java.util.Map; + public interface IBigBlueButtonInGW { void createMeeting2(String meetingID, boolean recorded, String voiceBridge); + // Users void setUserStatus(String meetingID, String userID, String status, Object value); - void getUsers(String meetingID, String requesterID); - void userLeft(String meetingID, String userID); - void userJoin(String meetingID, String userID, String username, String role, String externUserID); - void getCurrentPresenter(String meetingID, String requesterID); - void assignPresenter(String meetingID, String newPresenterID, String newPresenterName, String assignedBy); + + // Presentation + void clear(String meetingID); + void sendUpdateMessage(String meetingID, Map message); + void removePresentation(String meetingID, String presentationID); + void getPresentationInfo(String meetingID, String requesterID); + void sendCursorUpdate(String meetingID, double xPercent, double yPercent); + void resizeAndMoveSlide(String meetingID, double xOffset, double yOffset, double widthRatio, double heightRatio); + void gotoSlide(String meetingID, int slide); + void sharePresentation(String meetingID, String presentationID, boolean share); + void getSlideInfo(String meetingID, String requesterID); + } diff --git a/bigbluebutton-apps/src/main/scala/org/bigbluebutton/core/BigBlueButtonInGW.scala b/bigbluebutton-apps/src/main/scala/org/bigbluebutton/core/BigBlueButtonInGW.scala index 1c88893818..13fc140da2 100755 --- a/bigbluebutton-apps/src/main/scala/org/bigbluebutton/core/BigBlueButtonInGW.scala +++ b/bigbluebutton-apps/src/main/scala/org/bigbluebutton/core/BigBlueButtonInGW.scala @@ -9,6 +9,15 @@ import org.bigbluebutton.core.api.AssignPresenter import org.bigbluebutton.core.api.Role._ import org.bigbluebutton.core.api.IBigBlueButtonInGW import org.bigbluebutton.core.api.CreateMeeting +import org.bigbluebutton.core.api.ClearPresentation +import org.bigbluebutton.core.api.SendCursorUpdate +import org.bigbluebutton.core.api.PresentationConversionUpdate +import org.bigbluebutton.core.api.RemovePresentation +import org.bigbluebutton.core.api.GetPresentationInfo +import org.bigbluebutton.core.api.ResizeAndMoveSlide +import org.bigbluebutton.core.api.GotoSlide +import org.bigbluebutton.core.api.SharePresentation +import org.bigbluebutton.core.api.GetSlideInfo class BigBlueButtonInGW(bbbGW: BigBlueButtonGateway) extends IBigBlueButtonInGW { @@ -42,7 +51,45 @@ class BigBlueButtonInGW(bbbGW: BigBlueButtonGateway) extends IBigBlueButtonInGW // do nothing } - def createMeeting2(meetingID: String, record: Boolean, voiceBridge: String) = { + def createMeeting2(meetingID: String, record: Boolean, voiceBridge: String) { bbbGW.accept(new CreateMeeting(meetingID, record, voiceBridge)) } + + // Presentation + def clear(meetingID: String) { + bbbGW.accept(new ClearPresentation(meetingID)) + } + + def sendUpdateMessage(meetingID: String, message: java.util.Map[String, Object]) { + bbbGW.accept(new PresentationConversionUpdate(meetingID, message)) + } + + def removePresentation(meetingID: String, presentationID: String) { + bbbGW.accept(new RemovePresentation(meetingID, presentationID)) + } + + def getPresentationInfo(meetingID: String, requesterID: String) { + bbbGW.accept(new GetPresentationInfo(meetingID, requesterID)) + } + + def sendCursorUpdate(meetingID: String, xPercent: Double, yPercent: Double) { + bbbGW.accept(new SendCursorUpdate(meetingID, xPercent, yPercent)) + } + + def resizeAndMoveSlide(meetingID: String, xOffset: Double, yOffset: Double, widthRatio: Double, heightRatio: Double) { + bbbGW.accept(new ResizeAndMoveSlide(meetingID, xOffset, yOffset, widthRatio, heightRatio)) + } + + def gotoSlide(meetingID: String, slide: Int) { + bbbGW.accept(new GotoSlide(meetingID, slide)) + } + + def sharePresentation(meetingID: String, presentationID: String, share: Boolean) { + bbbGW.accept(new SharePresentation(meetingID, presentationID, share)) + } + + def getSlideInfo(meetingID: String, requesterID: String) { + bbbGW.accept(new GetSlideInfo(meetingID, requesterID)) + } + } \ No newline at end of file diff --git a/bigbluebutton-apps/src/main/scala/org/bigbluebutton/core/api/InMessages.scala b/bigbluebutton-apps/src/main/scala/org/bigbluebutton/core/api/InMessages.scala index f86481b2f5..3edeb9571e 100755 --- a/bigbluebutton-apps/src/main/scala/org/bigbluebutton/core/api/InMessages.scala +++ b/bigbluebutton-apps/src/main/scala/org/bigbluebutton/core/api/InMessages.scala @@ -1,6 +1,7 @@ package org.bigbluebutton.core.api import org.bigbluebutton.core.api.Role._ +import java.util.Map trait InMessage {val meetingID: String} @@ -9,10 +10,21 @@ case class DestroyMeeting(meetingID: String) extends InMessage case class StartMeeting(meetingID: String) extends InMessage case class EndMeeting(meetingID: String) extends InMessage +// Users case class UserJoining(meetingID: String, userID: String, name: String, role: Role, extUserID: String) extends InMessage case class UserLeaving(meetingID: String, userID: String) extends InMessage case class GetUsers(meetingID: String, requesterID: String) extends InMessage case class ChangeUserStatus(meetingID: String, userID: String, status: String, value: Object) extends InMessage case class AssignPresenter(meetingID: String, newPresenterID: String, newPresenterName: String, assignedBy: String) extends InMessage -case class SampleInMessage(meetingID: String) extends InMessage \ No newline at end of file +// Presentation +case class ClearPresentation(meetingID: String) extends InMessage +case class PresentationConversionUpdate(meetingID: String, msg: Map[String, Object]) extends InMessage +case class RemovePresentation(meetingID: String, presentationID: String) extends InMessage +case class GetPresentationInfo(meetingID: String, requesterID: String) extends InMessage +case class SendCursorUpdate(meetingID: String, xPercent: Double, yPercent: Double) extends InMessage +case class ResizeAndMoveSlide(meetingID: String, xOffset: Double, yOffset: Double, widthRatio: Double, heightRatio: Double) extends InMessage +case class GotoSlide(meetingID: String, slide: Int) extends InMessage +case class SharePresentation(meetingID: String, presentationID: String, share: Boolean) extends InMessage +case class GetSlideInfo(meetingID: String, requesterID: String) extends InMessage + diff --git a/bigbluebutton-apps/src/main/scala/org/bigbluebutton/core/api/OutMessages.scala b/bigbluebutton-apps/src/main/scala/org/bigbluebutton/core/api/OutMessages.scala index d72949ee5d..5daf9e57a0 100755 --- a/bigbluebutton-apps/src/main/scala/org/bigbluebutton/core/api/OutMessages.scala +++ b/bigbluebutton-apps/src/main/scala/org/bigbluebutton/core/api/OutMessages.scala @@ -7,6 +7,17 @@ case class MeetingDestroyed(meetingID: String) extends IOutMessage case class UserLeft(meetingID: String, isRecorded: Boolean, userID: String) extends IOutMessage case class PresenterAssigned(meetingID: String, recorded: Boolean, presenter: Presenter) extends IOutMessage +// Presentation +case class ClearPresentationOutMsg(meetingID: String, recorded: Boolean) extends IOutMessage +case class PresentationConversionUpdateOutMsg(meetingID: String, recorded: Boolean, msg: java.util.Map[String, Object]) extends IOutMessage +case class RemovePresentationOutMsg(meetingID: String, recorded: Boolean, presentationID: String) extends IOutMessage +case class GetPresentationInfoOutMsg(meetingID: String, recorded: Boolean, requesterID: String, info: java.util.Map[String, Object] ) extends IOutMessage +case class SendCursorUpdateOutMsg(meetingID: String, recorded: Boolean, xPercent: Double, yPercent: Double) extends IOutMessage +case class ResizeAndMoveSlideOutMsg(meetingID: String, recorded: Boolean, xOffset: Double, yOffset: Double, widthRatio: Double, heightRatio: Double) extends IOutMessage +case class GotoSlideOutMsg(meetingID: String, recorded: Boolean, slide: Int) extends IOutMessage +case class SharePresentationOutMsg(meetingID: String, recorded: Boolean, presentationID: String, share: Boolean) extends IOutMessage +case class GetSlideInfoOutMsg(meetingID: String, recorded: Boolean, requesterID: String, xOffset: Double, yOffset: Double, widthRatio: Double, heightRatio: Double) extends IOutMessage + // Value Objects case class MeetingVO(id: String, recorded: Boolean) diff --git a/bigbluebutton-apps/src/main/scala/org/bigbluebutton/core/apps/layout/LayoutApp.scala b/bigbluebutton-apps/src/main/scala/org/bigbluebutton/core/apps/layout/LayoutApp.scala new file mode 100755 index 0000000000..1499a015ac --- /dev/null +++ b/bigbluebutton-apps/src/main/scala/org/bigbluebutton/core/apps/layout/LayoutApp.scala @@ -0,0 +1,5 @@ +package org.bigbluebutton.core.apps.layout + +class LayoutApp { + +} \ No newline at end of file diff --git a/bigbluebutton-apps/src/main/scala/org/bigbluebutton/core/apps/presentation/PresentationApp.scala b/bigbluebutton-apps/src/main/scala/org/bigbluebutton/core/apps/presentation/PresentationApp.scala new file mode 100755 index 0000000000..1014e2a05f --- /dev/null +++ b/bigbluebutton-apps/src/main/scala/org/bigbluebutton/core/apps/presentation/PresentationApp.scala @@ -0,0 +1,84 @@ +package org.bigbluebutton.core.apps.presentation + +import org.bigbluebutton.core.api.InMessage +import org.bigbluebutton.core.api.MessageOutGateway +import org.bigbluebutton.core.api.ClearPresentation +import org.bigbluebutton.core.api.PresentationConversionUpdate +import org.bigbluebutton.core.api.RemovePresentation +import org.bigbluebutton.core.api.GetPresentationInfo +import org.bigbluebutton.core.api.SendCursorUpdate +import org.bigbluebutton.core.api.ResizeAndMoveSlide +import org.bigbluebutton.core.api.GotoSlide +import org.bigbluebutton.core.api.SharePresentation +import org.bigbluebutton.core.api.GetSlideInfo + +class PresentationApp(meetingID: String, recorded: Boolean, outGW: MessageOutGateway) { + + private var currentPresentation = "" + private var currentSlide = 0 + private var sharing = false + private var xOffset = 0D + private var yOffset = 0D + private var widthRatio = 1D + private var heightRatio = 1D + + /* cursor location */ + private var xPercent = 0D + private var yPercent = 0D + + private var presentationIDs = new java.util.ArrayList[String](); + + def handleMessage(msg: InMessage):Unit = { + msg match { + case clearPresentation: ClearPresentation => handleClearPresentation(clearPresentation) + case presentationConversionUpdate: PresentationConversionUpdate => handlePresentationConversionUpdate(presentationConversionUpdate) + case removePresentation: RemovePresentation => handleRemovePresentation(removePresentation) + case getPresentationInfo : GetPresentationInfo => handleGetPresentationInfo(getPresentationInfo) + case sendCursorUpdate : SendCursorUpdate => handleSendCursorUpdate(sendCursorUpdate) + case resizeAndMoveSlide: ResizeAndMoveSlide => handleResizeAndMoveSlide(resizeAndMoveSlide) + case gotoSlide: GotoSlide => handleGotoSlide(gotoSlide) + case sharePresentation: SharePresentation => handleSharePresentation(sharePresentation) + case getSlideInfo: GetSlideInfo => handleGetSlideInfo(getSlideInfo) + case _ => // do nothing + } + } + + private def handleClearPresentation(msg: ClearPresentation) { + currentPresentation = "" + sharing = false + + } + + private def handlePresentationConversionUpdate(msg: PresentationConversionUpdate) { + + } + + private def handleRemovePresentation(msg: RemovePresentation) { + + } + + private def handleGetPresentationInfo(msg: GetPresentationInfo) { + + } + + private def handleSendCursorUpdate(msg: SendCursorUpdate) { + + } + + private def handleResizeAndMoveSlide(msg: ResizeAndMoveSlide) { + + } + + private def handleGotoSlide(msg: GotoSlide) { + + } + + private def handleSharePresentation(msg: SharePresentation) { + + } + + private def handleGetSlideInfo(msg: GetSlideInfo) { + + } + +} \ No newline at end of file diff --git a/bigbluebutton-apps/src/main/scala/org/bigbluebutton/core/apps/presentation/red5/PresentationClientMessageSender.scala b/bigbluebutton-apps/src/main/scala/org/bigbluebutton/core/apps/presentation/red5/PresentationClientMessageSender.scala new file mode 100755 index 0000000000..b5b84bf815 --- /dev/null +++ b/bigbluebutton-apps/src/main/scala/org/bigbluebutton/core/apps/presentation/red5/PresentationClientMessageSender.scala @@ -0,0 +1,155 @@ +package org.bigbluebutton.core.apps.presentation.red5 + +import org.bigbluebutton.conference.meeting.messaging.red5.ConnectionInvokerService +import org.bigbluebutton.core.api.OutMessageListener2 +import org.bigbluebutton.core.api.IOutMessage +import org.bigbluebutton.core.api.ClearPresentationOutMsg +import org.bigbluebutton.core.api.PresentationConversionUpdateOutMsg +import org.bigbluebutton.core.api.RemovePresentationOutMsg +import org.bigbluebutton.core.api.GetPresentationInfoOutMsg +import org.bigbluebutton.core.api.SendCursorUpdateOutMsg +import org.bigbluebutton.core.api.ResizeAndMoveSlideOutMsg +import org.bigbluebutton.core.api.GotoSlideOutMsg +import org.bigbluebutton.core.api.SharePresentationOutMsg +import org.bigbluebutton.core.api.GetSlideInfoOutMsg +import org.bigbluebutton.conference.meeting.messaging.red5.BroadcastClientMessage +import org.bigbluebutton.conference.meeting.messaging.red5.DirectClientMessage +import collection.JavaConversions._ + +class PresentationClientMessageSender(service: ConnectionInvokerService) extends OutMessageListener2 { + private val OFFICE_DOC_CONVERSION_SUCCESS_KEY = "OFFICE_DOC_CONVERSION_SUCCESS"; + private val OFFICE_DOC_CONVERSION_FAILED_KEY = "OFFICE_DOC_CONVERSION_FAILED"; + private val SUPPORTED_DOCUMENT_KEY = "SUPPORTED_DOCUMENT"; + private val UNSUPPORTED_DOCUMENT_KEY = "UNSUPPORTED_DOCUMENT"; + private val PAGE_COUNT_FAILED_KEY = "PAGE_COUNT_FAILED"; + private val PAGE_COUNT_EXCEEDED_KEY = "PAGE_COUNT_EXCEEDED"; + private val GENERATED_SLIDE_KEY = "GENERATED_SLIDE"; + private val GENERATING_THUMBNAIL_KEY = "GENERATING_THUMBNAIL"; + private val GENERATED_THUMBNAIL_KEY = "GENERATED_THUMBNAIL"; + private val CONVERSION_COMPLETED_KEY = "CONVERSION_COMPLETED"; + + def handleMessage(msg: IOutMessage) { + msg match { + case clearPresentationOutMsg: ClearPresentationOutMsg => handleClearPresentationOutMsg(clearPresentationOutMsg) + case presentationConversionUpdateOutMsg: PresentationConversionUpdateOutMsg => handlePresentationConversionUpdateOutMsg(presentationConversionUpdateOutMsg) + case removePresentationOutMsg: RemovePresentationOutMsg => handleRemovePresentationOutMsg(removePresentationOutMsg) + case getPresentationInfoOutMsg: GetPresentationInfoOutMsg => handleGetPresentationInfoOutMsg(getPresentationInfoOutMsg) + case sendCursorUpdateOutMsg: SendCursorUpdateOutMsg => handleSendCursorUpdateOutMsg(sendCursorUpdateOutMsg) + case resizeAndMoveSlideOutMsg: ResizeAndMoveSlideOutMsg => handleResizeAndMoveSlideOutMsg(resizeAndMoveSlideOutMsg) + case gotoSlideOutMsg: GotoSlideOutMsg => handleGotoSlideOutMsg(gotoSlideOutMsg) + case sharePresentationOutMsg: SharePresentationOutMsg => handleSharePresentationOutMsg(sharePresentationOutMsg) + case getSlideInfoOutMsg: GetSlideInfoOutMsg => handleGetSlideInfoOutMsg(getSlideInfoOutMsg) + case _ => // do nothing + } + } + + private def handleClearPresentationOutMsg(msg: ClearPresentationOutMsg) { + + } + + private def handlePresentationConversionUpdateOutMsg(msg: PresentationConversionUpdateOutMsg) { + val message = msg.msg; + + val messageKey:String = message.get("messageKey").asInstanceOf[String] + + val args = new java.util.HashMap[String, Object](); + args.put("meetingID", message.get("conference")); + args.put("code", message.get("returnCode")); + args.put("presentationID", message.get("presentationName")); + args.put("messageKey", messageKey); + + if (messageKey.equalsIgnoreCase(OFFICE_DOC_CONVERSION_SUCCESS_KEY) || + messageKey.equalsIgnoreCase(OFFICE_DOC_CONVERSION_FAILED_KEY) || + messageKey.equalsIgnoreCase(SUPPORTED_DOCUMENT_KEY) || + messageKey.equalsIgnoreCase(UNSUPPORTED_DOCUMENT_KEY) || + messageKey.equalsIgnoreCase(GENERATING_THUMBNAIL_KEY) || + messageKey.equalsIgnoreCase(GENERATED_THUMBNAIL_KEY) || + messageKey.equalsIgnoreCase(PAGE_COUNT_FAILED_KEY)){ + + val m = new BroadcastClientMessage(msg.meetingID, "conversionUpdateMessageCallback", args); + service.sendMessage(m); + } else if(messageKey.equalsIgnoreCase(PAGE_COUNT_EXCEEDED_KEY)){ + args.put("numberOfPages", message.get("numberOfPages")); + args.put("maxNumberPages", message.get("maxNumberPages")); + + val m = new BroadcastClientMessage(msg.meetingID, "pageCountExceededUpdateMessageCallback", args); + service.sendMessage(m); + + } else if(messageKey.equalsIgnoreCase(GENERATED_SLIDE_KEY)){ + args.put("numberOfPages", message.get("numberOfPages")); + args.put("pagesCompleted", message.get("pagesCompleted")); + + val m = new BroadcastClientMessage(msg.meetingID, "generatedSlideUpdateMessageCallback", args); + service.sendMessage(m); + + } else if(messageKey.equalsIgnoreCase(CONVERSION_COMPLETED_KEY)){ + args.put("slidesInfo", message.get("slidesInfo")); + + val m = new BroadcastClientMessage(msg.meetingID, "conversionCompletedUpdateMessageCallback", args); + service.sendMessage(m); + } + } + + private def handleRemovePresentationOutMsg(msg: RemovePresentationOutMsg) { + val args = new java.util.HashMap[String, Object](); + args.put("presentationID", msg.presentationID); + + val m = new BroadcastClientMessage(msg.meetingID, "removePresentationCallback", args); + service.sendMessage(m); + } + + private def handleGetPresentationInfoOutMsg(msg: GetPresentationInfoOutMsg) { + val message = msg.info; + val m = new DirectClientMessage(msg.meetingID, msg.requesterID, "getPresentationInfoReply", msg.info); + service.sendMessage(m); + + } + + private def handleSendCursorUpdateOutMsg(msg: SendCursorUpdateOutMsg) { + val args = new java.util.HashMap[String, Object](); + args.put("xPercent", msg.xPercent:java.lang.Double); + args.put("yPercent", msg.yPercent:java.lang.Double); + + val m = new BroadcastClientMessage(msg.meetingID, "PresentationCursorUpdateCommand", args); + service.sendMessage(m); + } + + private def handleResizeAndMoveSlideOutMsg(msg: ResizeAndMoveSlideOutMsg) { + val args = new java.util.HashMap[String, Object](); + args.put("xOffset", msg.xOffset:java.lang.Double); + args.put("yOffest", msg.yOffset:java.lang.Double); + args.put("widthRatio", msg.widthRatio:java.lang.Double); + args.put("heightRatio", msg.heightRatio:java.lang.Double); + + val m = new BroadcastClientMessage(msg.meetingID, "moveCallback", args); + service.sendMessage(m); + } + + private def handleGotoSlideOutMsg(msg: GotoSlideOutMsg) { + val args = new java.util.HashMap[String, Object](); + args.put("pageNum", msg.slide:java.lang.Integer); + + val m = new BroadcastClientMessage(msg.meetingID, "gotoSlideCallback", args); + service.sendMessage(m); + } + + private def handleSharePresentationOutMsg(msg: SharePresentationOutMsg) { + val args = new java.util.HashMap[String, Object](); + args.put("presentationID", msg.presentationID); + args.put("share", msg.share:java.lang.Boolean); + + val m = new BroadcastClientMessage(msg.meetingID, "sharePresentationCallback", args); + service.sendMessage(m); + } + + private def handleGetSlideInfoOutMsg(msg: GetSlideInfoOutMsg) { + val args = new java.util.HashMap[String, Object](); + args.put("xOffset", msg.xOffset:java.lang.Double); + args.put("yOffest", msg.yOffset:java.lang.Double); + args.put("widthRatio", msg.widthRatio:java.lang.Double); + args.put("heightRatio", msg.heightRatio:java.lang.Double); + + val m = new DirectClientMessage(msg.meetingID, msg.requesterID, "getPresentationInfoReply", args); + service.sendMessage(m); + } +} \ No newline at end of file