From e6bc58de03bb604c1f6a31f4a6cb7fa0f7005026 Mon Sep 17 00:00:00 2001 From: Aniket Kadam Date: Mon, 29 Apr 2024 12:31:49 +0530 Subject: [PATCH 01/14] Update versions Signed-off-by: Aniket Kadam --- gradle.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index 0f9cc9d56..8c8acdb01 100644 --- a/gradle.properties +++ b/gradle.properties @@ -19,8 +19,8 @@ android.useAndroidX=true android.enableJetifier=true # Kotlin code style for this project: "official" or "obsolete": kotlin.code.style=official -100MS_APP_VERSION_CODE=371 -100MS_APP_VERSION_NAME=5.0.5 +100MS_APP_VERSION_CODE=372 +100MS_APP_VERSION_NAME=5.0.6 hmsRoomKitGroup=live.100ms HMS_ROOM_KIT_VERSION=1.2.11 android.suppressUnsupportedCompileSdk=33 From 934e35e38c05bd206048fbaf598c2e94b188c5a3 Mon Sep 17 00:00:00 2001 From: Decoder07 Date: Wed, 8 May 2024 17:29:23 +0530 Subject: [PATCH 02/14] Updated whiteboard logic in room kit --- .../roomkit/ui/meeting/MeetingViewModel.kt | 38 +++++++++++++------ .../ui/meeting/SessionOptionBottomSheet.kt | 6 +-- .../ui/meeting/videogrid/VideoGridFragment.kt | 10 ++--- 3 files changed, 35 insertions(+), 19 deletions(-) diff --git a/room-kit/src/main/java/live/hms/roomkit/ui/meeting/MeetingViewModel.kt b/room-kit/src/main/java/live/hms/roomkit/ui/meeting/MeetingViewModel.kt index 8914d882c..27dbf57a9 100644 --- a/room-kit/src/main/java/live/hms/roomkit/ui/meeting/MeetingViewModel.kt +++ b/room-kit/src/main/java/live/hms/roomkit/ui/meeting/MeetingViewModel.kt @@ -194,11 +194,28 @@ class MeetingViewModel( val showWhiteBoardFullScreenSingleLiveEvent by lazy { SingleLiveEvent() } val debounceWhiteBoardObserver = showHideWhiteboardObserver.debounce(coroutineScope = viewModelScope) + fun isWhiteboardOpen(): Boolean{ + closeWhiteBoard.value?.let {isWhiteboardClosed -> + return isWhiteboardClosed.not() + } + return false + } + + fun isOwner():Boolean{ + val localPeer = hmsSDK.getLocalPeer() + localPeer?.let {_localPeer -> + if(_localPeer.customerUserID == showHideWhiteboardObserver.value?.owner?.customerUserID){ + return true + } + } + return false + } + private fun setupWhiteBoardListener() { localHmsInteractivityCenter.setWhiteboardUpdateListener(object : HMSWhiteboardUpdateListener { override fun onUpdate(hmsWhiteboardUpdate: HMSWhiteboardUpdate) { when(hmsWhiteboardUpdate) { - is HMSWhiteboardUpdate.Start -> showHideWhiteboardObserver.postValue(hmsWhiteboardUpdate.hmsWhiteboard) + is HMSWhiteboardUpdate.Start -> if(isWhiteboardOpen().not())showHideWhiteboardObserver.postValue(hmsWhiteboardUpdate.hmsWhiteboard) is HMSWhiteboardUpdate.Stop -> showHideWhiteboardObserver.postValue(hmsWhiteboardUpdate.hmsWhiteboard) } } @@ -208,12 +225,10 @@ class MeetingViewModel( fun toggleWhiteBoard() { - val currentWhiteBoardState = showHideWhiteboardObserver.value - - if (currentWhiteBoardState?.isOpen == true && currentWhiteBoardState.isOwner.not()) + if (isWhiteboardOpen() && isOwner().not()) return - if (currentWhiteBoardState?.isOpen == true) { + if (isWhiteboardOpen()) { stopCurrentWhiteBoardSession() closeWhiteBoard.value = true } else { @@ -224,7 +239,7 @@ class MeetingViewModel( private fun startWhiteBoardSession() { val currentWhiteBoardState = showHideWhiteboardObserver.value //make sure you are the owner and whiteboard is open to close the whiteboard - if (currentWhiteBoardState?.isOpen == true && currentWhiteBoardState.isOwner.not()) + if (isWhiteboardOpen() && isOwner().not()) return if (hmsSDK.isScreenShared()) { @@ -239,23 +254,24 @@ class MeetingViewModel( } - if (currentWhiteBoardState == null || currentWhiteBoardState?.isOpen == false) { + if (currentWhiteBoardState == null || !isWhiteboardOpen()) { localHmsInteractivityCenter.startWhiteboard( title = UUID.randomUUID().toString(), object : HMSActionResultListener { override fun onError(error: HMSException) {} - override fun onSuccess() {} + override fun onSuccess() { + closeWhiteBoard.value = false + } }) } } fun stopCurrentWhiteBoardSession() { - val currentWhiteBoardState = showHideWhiteboardObserver.value - if (currentWhiteBoardState?.isOpen == true && currentWhiteBoardState.isOwner.not()) + if (isWhiteboardOpen() && isOwner().not()) return - if (currentWhiteBoardState?.isOpen == true) { + if (isWhiteboardOpen()) { localHmsInteractivityCenter.stopWhiteboard(object : HMSActionResultListener{ override fun onError(error: HMSException) {} override fun onSuccess() {} diff --git a/room-kit/src/main/java/live/hms/roomkit/ui/meeting/SessionOptionBottomSheet.kt b/room-kit/src/main/java/live/hms/roomkit/ui/meeting/SessionOptionBottomSheet.kt index 811914427..4cfcdc6db 100644 --- a/room-kit/src/main/java/live/hms/roomkit/ui/meeting/SessionOptionBottomSheet.kt +++ b/room-kit/src/main/java/live/hms/roomkit/ui/meeting/SessionOptionBottomSheet.kt @@ -228,10 +228,10 @@ class SessionOptionBottomSheet( } meetingViewModel.showHideWhiteboardObserver.observe(viewLifecycleOwner) { - whiteboard.setSelectedButton(it.isOpen) + whiteboard.setSelectedButton(meetingViewModel.isWhiteboardOpen()) whiteboard.setText( - if (it.isOpen && it.isOwner) resources.getString(R.string.stop_white_board) - else if(it.isOpen.not()) resources.getString(R.string.start_white_board) + if (meetingViewModel.isWhiteboardOpen() && meetingViewModel.isOwner()) resources.getString(R.string.stop_white_board) + else if(meetingViewModel.isWhiteboardOpen().not()) resources.getString(R.string.start_white_board) else resources.getString(R.string.stop_white_board) ) diff --git a/room-kit/src/main/java/live/hms/roomkit/ui/meeting/videogrid/VideoGridFragment.kt b/room-kit/src/main/java/live/hms/roomkit/ui/meeting/videogrid/VideoGridFragment.kt index c2e2a1e86..fa371910c 100644 --- a/room-kit/src/main/java/live/hms/roomkit/ui/meeting/videogrid/VideoGridFragment.kt +++ b/room-kit/src/main/java/live/hms/roomkit/ui/meeting/videogrid/VideoGridFragment.kt @@ -87,7 +87,7 @@ class VideoGridFragment : Fragment() { meetingViewModel.debounceWhiteBoardObserver.observe(viewLifecycleOwner) { - if (it.isOpen) { + if (meetingViewModel.isWhiteboardOpen()) { addOrRemoveWebView(shouldAddWebView = true) whiteboardView?.show() binding.webViewContainer.show() @@ -427,8 +427,8 @@ class VideoGridFragment : Fragment() { var newRowCount = 0 var newColumnCount = 0 var newGuideLinePercentage = 0f - val showDockedState = screenShareTrackList.isEmpty().not() || whiteBoard?.isOpen == true - val hasScreenShareOverriddenWhiteboard = screenShareTrackList.isEmpty().not() && whiteBoard?.isOpen == true + val showDockedState = screenShareTrackList.isEmpty().not() || meetingViewModel.isWhiteboardOpen() + val hasScreenShareOverriddenWhiteboard = screenShareTrackList.isEmpty().not() && meetingViewModel.isWhiteboardOpen() meetingViewModel.showhasScreenShareOverriddenWhiteboardError(hasScreenShareOverriddenWhiteboard) @@ -438,8 +438,8 @@ class VideoGridFragment : Fragment() { * 75% white board view port */ newGuideLinePercentage = if (screenShareTrackList.isEmpty().not()) 0.75f - else if (whiteBoard?.isOpen == true && isWhiteBoardFullScreen == true) 1.0f - else if (whiteBoard?.isOpen == true) 0.75f + else if (meetingViewModel.isWhiteboardOpen() && isWhiteBoardFullScreen == true) 1.0f + else if (meetingViewModel.isWhiteboardOpen()) 0.75f else 0f //is screen share track is present then reduce the grid and column span else restore From 64f648527b32408df8b7ecc6a13c4651f7ba92d4 Mon Sep 17 00:00:00 2001 From: Aniket Kadam Date: Fri, 10 May 2024 12:23:38 +0530 Subject: [PATCH 03/14] Revert "AN-1558: Updated whiteboard logic in room kit" --- .../roomkit/ui/meeting/MeetingViewModel.kt | 38 ++++++------------- .../ui/meeting/SessionOptionBottomSheet.kt | 6 +-- .../ui/meeting/videogrid/VideoGridFragment.kt | 10 ++--- 3 files changed, 19 insertions(+), 35 deletions(-) diff --git a/room-kit/src/main/java/live/hms/roomkit/ui/meeting/MeetingViewModel.kt b/room-kit/src/main/java/live/hms/roomkit/ui/meeting/MeetingViewModel.kt index 27dbf57a9..8914d882c 100644 --- a/room-kit/src/main/java/live/hms/roomkit/ui/meeting/MeetingViewModel.kt +++ b/room-kit/src/main/java/live/hms/roomkit/ui/meeting/MeetingViewModel.kt @@ -194,28 +194,11 @@ class MeetingViewModel( val showWhiteBoardFullScreenSingleLiveEvent by lazy { SingleLiveEvent() } val debounceWhiteBoardObserver = showHideWhiteboardObserver.debounce(coroutineScope = viewModelScope) - fun isWhiteboardOpen(): Boolean{ - closeWhiteBoard.value?.let {isWhiteboardClosed -> - return isWhiteboardClosed.not() - } - return false - } - - fun isOwner():Boolean{ - val localPeer = hmsSDK.getLocalPeer() - localPeer?.let {_localPeer -> - if(_localPeer.customerUserID == showHideWhiteboardObserver.value?.owner?.customerUserID){ - return true - } - } - return false - } - private fun setupWhiteBoardListener() { localHmsInteractivityCenter.setWhiteboardUpdateListener(object : HMSWhiteboardUpdateListener { override fun onUpdate(hmsWhiteboardUpdate: HMSWhiteboardUpdate) { when(hmsWhiteboardUpdate) { - is HMSWhiteboardUpdate.Start -> if(isWhiteboardOpen().not())showHideWhiteboardObserver.postValue(hmsWhiteboardUpdate.hmsWhiteboard) + is HMSWhiteboardUpdate.Start -> showHideWhiteboardObserver.postValue(hmsWhiteboardUpdate.hmsWhiteboard) is HMSWhiteboardUpdate.Stop -> showHideWhiteboardObserver.postValue(hmsWhiteboardUpdate.hmsWhiteboard) } } @@ -225,10 +208,12 @@ class MeetingViewModel( fun toggleWhiteBoard() { - if (isWhiteboardOpen() && isOwner().not()) + val currentWhiteBoardState = showHideWhiteboardObserver.value + + if (currentWhiteBoardState?.isOpen == true && currentWhiteBoardState.isOwner.not()) return - if (isWhiteboardOpen()) { + if (currentWhiteBoardState?.isOpen == true) { stopCurrentWhiteBoardSession() closeWhiteBoard.value = true } else { @@ -239,7 +224,7 @@ class MeetingViewModel( private fun startWhiteBoardSession() { val currentWhiteBoardState = showHideWhiteboardObserver.value //make sure you are the owner and whiteboard is open to close the whiteboard - if (isWhiteboardOpen() && isOwner().not()) + if (currentWhiteBoardState?.isOpen == true && currentWhiteBoardState.isOwner.not()) return if (hmsSDK.isScreenShared()) { @@ -254,24 +239,23 @@ class MeetingViewModel( } - if (currentWhiteBoardState == null || !isWhiteboardOpen()) { + if (currentWhiteBoardState == null || currentWhiteBoardState?.isOpen == false) { localHmsInteractivityCenter.startWhiteboard( title = UUID.randomUUID().toString(), object : HMSActionResultListener { override fun onError(error: HMSException) {} - override fun onSuccess() { - closeWhiteBoard.value = false - } + override fun onSuccess() {} }) } } fun stopCurrentWhiteBoardSession() { + val currentWhiteBoardState = showHideWhiteboardObserver.value - if (isWhiteboardOpen() && isOwner().not()) + if (currentWhiteBoardState?.isOpen == true && currentWhiteBoardState.isOwner.not()) return - if (isWhiteboardOpen()) { + if (currentWhiteBoardState?.isOpen == true) { localHmsInteractivityCenter.stopWhiteboard(object : HMSActionResultListener{ override fun onError(error: HMSException) {} override fun onSuccess() {} diff --git a/room-kit/src/main/java/live/hms/roomkit/ui/meeting/SessionOptionBottomSheet.kt b/room-kit/src/main/java/live/hms/roomkit/ui/meeting/SessionOptionBottomSheet.kt index 4cfcdc6db..811914427 100644 --- a/room-kit/src/main/java/live/hms/roomkit/ui/meeting/SessionOptionBottomSheet.kt +++ b/room-kit/src/main/java/live/hms/roomkit/ui/meeting/SessionOptionBottomSheet.kt @@ -228,10 +228,10 @@ class SessionOptionBottomSheet( } meetingViewModel.showHideWhiteboardObserver.observe(viewLifecycleOwner) { - whiteboard.setSelectedButton(meetingViewModel.isWhiteboardOpen()) + whiteboard.setSelectedButton(it.isOpen) whiteboard.setText( - if (meetingViewModel.isWhiteboardOpen() && meetingViewModel.isOwner()) resources.getString(R.string.stop_white_board) - else if(meetingViewModel.isWhiteboardOpen().not()) resources.getString(R.string.start_white_board) + if (it.isOpen && it.isOwner) resources.getString(R.string.stop_white_board) + else if(it.isOpen.not()) resources.getString(R.string.start_white_board) else resources.getString(R.string.stop_white_board) ) diff --git a/room-kit/src/main/java/live/hms/roomkit/ui/meeting/videogrid/VideoGridFragment.kt b/room-kit/src/main/java/live/hms/roomkit/ui/meeting/videogrid/VideoGridFragment.kt index fa371910c..c2e2a1e86 100644 --- a/room-kit/src/main/java/live/hms/roomkit/ui/meeting/videogrid/VideoGridFragment.kt +++ b/room-kit/src/main/java/live/hms/roomkit/ui/meeting/videogrid/VideoGridFragment.kt @@ -87,7 +87,7 @@ class VideoGridFragment : Fragment() { meetingViewModel.debounceWhiteBoardObserver.observe(viewLifecycleOwner) { - if (meetingViewModel.isWhiteboardOpen()) { + if (it.isOpen) { addOrRemoveWebView(shouldAddWebView = true) whiteboardView?.show() binding.webViewContainer.show() @@ -427,8 +427,8 @@ class VideoGridFragment : Fragment() { var newRowCount = 0 var newColumnCount = 0 var newGuideLinePercentage = 0f - val showDockedState = screenShareTrackList.isEmpty().not() || meetingViewModel.isWhiteboardOpen() - val hasScreenShareOverriddenWhiteboard = screenShareTrackList.isEmpty().not() && meetingViewModel.isWhiteboardOpen() + val showDockedState = screenShareTrackList.isEmpty().not() || whiteBoard?.isOpen == true + val hasScreenShareOverriddenWhiteboard = screenShareTrackList.isEmpty().not() && whiteBoard?.isOpen == true meetingViewModel.showhasScreenShareOverriddenWhiteboardError(hasScreenShareOverriddenWhiteboard) @@ -438,8 +438,8 @@ class VideoGridFragment : Fragment() { * 75% white board view port */ newGuideLinePercentage = if (screenShareTrackList.isEmpty().not()) 0.75f - else if (meetingViewModel.isWhiteboardOpen() && isWhiteBoardFullScreen == true) 1.0f - else if (meetingViewModel.isWhiteboardOpen()) 0.75f + else if (whiteBoard?.isOpen == true && isWhiteBoardFullScreen == true) 1.0f + else if (whiteBoard?.isOpen == true) 0.75f else 0f //is screen share track is present then reduce the grid and column span else restore From c0e924ac612f992bd91b7210aa3998aa882af133 Mon Sep 17 00:00:00 2001 From: Gulzar Date: Fri, 10 May 2024 14:08:25 +0530 Subject: [PATCH 04/14] Update MeetingViewModel.kt --- .../main/java/live/hms/roomkit/ui/meeting/MeetingViewModel.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/room-kit/src/main/java/live/hms/roomkit/ui/meeting/MeetingViewModel.kt b/room-kit/src/main/java/live/hms/roomkit/ui/meeting/MeetingViewModel.kt index 8914d882c..db03327ab 100644 --- a/room-kit/src/main/java/live/hms/roomkit/ui/meeting/MeetingViewModel.kt +++ b/room-kit/src/main/java/live/hms/roomkit/ui/meeting/MeetingViewModel.kt @@ -314,7 +314,6 @@ class MeetingViewModel( fun setupFilterVideoPlugin() { if (hmsSDK.getPlugins().isNullOrEmpty() && hmsSDK.getLocalPeer()?.videoTrack != null ) { - filterPlugin.init() hmsSDK.addPlugin(filterPlugin, object : HMSActionResultListener { override fun onError(error: HMSException) { From f496912258349dec84b5f2619968c9074d998f3f Mon Sep 17 00:00:00 2001 From: Gulzar Date: Fri, 10 May 2024 16:35:42 +0530 Subject: [PATCH 05/14] added changes --- .../live/hms/roomkit/ui/meeting/MeetingViewModel.kt | 13 +++++++------ .../roomkit/ui/meeting/SessionOptionBottomSheet.kt | 7 ++++--- .../ui/meeting/videogrid/VideoGridFragment.kt | 13 +++++++------ 3 files changed, 18 insertions(+), 15 deletions(-) diff --git a/room-kit/src/main/java/live/hms/roomkit/ui/meeting/MeetingViewModel.kt b/room-kit/src/main/java/live/hms/roomkit/ui/meeting/MeetingViewModel.kt index db03327ab..517f7d587 100644 --- a/room-kit/src/main/java/live/hms/roomkit/ui/meeting/MeetingViewModel.kt +++ b/room-kit/src/main/java/live/hms/roomkit/ui/meeting/MeetingViewModel.kt @@ -66,6 +66,7 @@ import live.hms.video.utils.HMSLogger import live.hms.video.whiteboard.HMSWhiteboard import live.hms.video.whiteboard.HMSWhiteboardUpdate import live.hms.video.whiteboard.HMSWhiteboardUpdateListener +import live.hms.video.whiteboard.State import live.hms.videofilters.HMSVideoFilter import java.util.* import kotlin.collections.ArrayList @@ -210,10 +211,10 @@ class MeetingViewModel( val currentWhiteBoardState = showHideWhiteboardObserver.value - if (currentWhiteBoardState?.isOpen == true && currentWhiteBoardState.isOwner.not()) + if (currentWhiteBoardState?.state == State.Started && currentWhiteBoardState.isOwner.not()) return - if (currentWhiteBoardState?.isOpen == true) { + if (currentWhiteBoardState?.state == State.Started) { stopCurrentWhiteBoardSession() closeWhiteBoard.value = true } else { @@ -224,7 +225,7 @@ class MeetingViewModel( private fun startWhiteBoardSession() { val currentWhiteBoardState = showHideWhiteboardObserver.value //make sure you are the owner and whiteboard is open to close the whiteboard - if (currentWhiteBoardState?.isOpen == true && currentWhiteBoardState.isOwner.not()) + if (currentWhiteBoardState?.state == State.Started && currentWhiteBoardState.isOwner.not()) return if (hmsSDK.isScreenShared()) { @@ -239,7 +240,7 @@ class MeetingViewModel( } - if (currentWhiteBoardState == null || currentWhiteBoardState?.isOpen == false) { + if (currentWhiteBoardState == null || currentWhiteBoardState?.state == State.Stopped) { localHmsInteractivityCenter.startWhiteboard( title = UUID.randomUUID().toString(), object : HMSActionResultListener { @@ -252,10 +253,10 @@ class MeetingViewModel( fun stopCurrentWhiteBoardSession() { val currentWhiteBoardState = showHideWhiteboardObserver.value - if (currentWhiteBoardState?.isOpen == true && currentWhiteBoardState.isOwner.not()) + if (currentWhiteBoardState?.state == State.Started && currentWhiteBoardState.isOwner.not()) return - if (currentWhiteBoardState?.isOpen == true) { + if (currentWhiteBoardState?.state == State.Started) { localHmsInteractivityCenter.stopWhiteboard(object : HMSActionResultListener{ override fun onError(error: HMSException) {} override fun onSuccess() {} diff --git a/room-kit/src/main/java/live/hms/roomkit/ui/meeting/SessionOptionBottomSheet.kt b/room-kit/src/main/java/live/hms/roomkit/ui/meeting/SessionOptionBottomSheet.kt index 811914427..bb8b155c4 100644 --- a/room-kit/src/main/java/live/hms/roomkit/ui/meeting/SessionOptionBottomSheet.kt +++ b/room-kit/src/main/java/live/hms/roomkit/ui/meeting/SessionOptionBottomSheet.kt @@ -22,6 +22,7 @@ import live.hms.roomkit.ui.theme.HMSPrebuiltTheme import live.hms.roomkit.ui.theme.getColorOrDefault import live.hms.roomkit.util.viewLifecycle import live.hms.video.sdk.models.enums.HMSRecordingState +import live.hms.video.whiteboard.State class SessionOptionBottomSheet( private val onScreenShareClicked: () -> Unit, @@ -228,10 +229,10 @@ class SessionOptionBottomSheet( } meetingViewModel.showHideWhiteboardObserver.observe(viewLifecycleOwner) { - whiteboard.setSelectedButton(it.isOpen) + whiteboard.setSelectedButton(it.state == State.Started) whiteboard.setText( - if (it.isOpen && it.isOwner) resources.getString(R.string.stop_white_board) - else if(it.isOpen.not()) resources.getString(R.string.start_white_board) + if (it.state == State.Started && it.isOwner) resources.getString(R.string.stop_white_board) + else if(it.state == State.Stopped) resources.getString(R.string.start_white_board) else resources.getString(R.string.stop_white_board) ) diff --git a/room-kit/src/main/java/live/hms/roomkit/ui/meeting/videogrid/VideoGridFragment.kt b/room-kit/src/main/java/live/hms/roomkit/ui/meeting/videogrid/VideoGridFragment.kt index c2e2a1e86..ae8550275 100644 --- a/room-kit/src/main/java/live/hms/roomkit/ui/meeting/videogrid/VideoGridFragment.kt +++ b/room-kit/src/main/java/live/hms/roomkit/ui/meeting/videogrid/VideoGridFragment.kt @@ -40,6 +40,7 @@ import live.hms.roomkit.util.contextSafe import live.hms.roomkit.util.viewLifecycle import live.hms.roomkit.util.visibilityOpacity import live.hms.video.sdk.models.enums.HMSPeerUpdate +import live.hms.video.whiteboard.State import live.hms.videoview.HMSVideoView class VideoGridFragment : Fragment() { @@ -86,8 +87,8 @@ class VideoGridFragment : Fragment() { private fun initWhiteBoard() { - meetingViewModel.debounceWhiteBoardObserver.observe(viewLifecycleOwner) { - if (it.isOpen) { + meetingViewModel.showHideWhiteboardObserver.observe(viewLifecycleOwner) { + if (it.state == State.Started) { addOrRemoveWebView(shouldAddWebView = true) whiteboardView?.show() binding.webViewContainer.show() @@ -427,8 +428,8 @@ class VideoGridFragment : Fragment() { var newRowCount = 0 var newColumnCount = 0 var newGuideLinePercentage = 0f - val showDockedState = screenShareTrackList.isEmpty().not() || whiteBoard?.isOpen == true - val hasScreenShareOverriddenWhiteboard = screenShareTrackList.isEmpty().not() && whiteBoard?.isOpen == true + val showDockedState = screenShareTrackList.isEmpty().not() || whiteBoard?.state == State.Started + val hasScreenShareOverriddenWhiteboard = screenShareTrackList.isEmpty().not() && whiteBoard?.state == State.Started meetingViewModel.showhasScreenShareOverriddenWhiteboardError(hasScreenShareOverriddenWhiteboard) @@ -438,8 +439,8 @@ class VideoGridFragment : Fragment() { * 75% white board view port */ newGuideLinePercentage = if (screenShareTrackList.isEmpty().not()) 0.75f - else if (whiteBoard?.isOpen == true && isWhiteBoardFullScreen == true) 1.0f - else if (whiteBoard?.isOpen == true) 0.75f + else if (whiteBoard?.state == State.Started && isWhiteBoardFullScreen == true) 1.0f + else if (whiteBoard?.state == State.Started) 0.75f else 0f //is screen share track is present then reduce the grid and column span else restore From 73e42306c39b4ee0e6fdd10d051d55e11de70d47 Mon Sep 17 00:00:00 2001 From: Gulzar Date: Fri, 10 May 2024 17:39:24 +0530 Subject: [PATCH 06/14] Update VideoGridFragment.kt --- .../live/hms/roomkit/ui/meeting/videogrid/VideoGridFragment.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/room-kit/src/main/java/live/hms/roomkit/ui/meeting/videogrid/VideoGridFragment.kt b/room-kit/src/main/java/live/hms/roomkit/ui/meeting/videogrid/VideoGridFragment.kt index ae8550275..fc94bafe0 100644 --- a/room-kit/src/main/java/live/hms/roomkit/ui/meeting/videogrid/VideoGridFragment.kt +++ b/room-kit/src/main/java/live/hms/roomkit/ui/meeting/videogrid/VideoGridFragment.kt @@ -87,7 +87,7 @@ class VideoGridFragment : Fragment() { private fun initWhiteBoard() { - meetingViewModel.showHideWhiteboardObserver.observe(viewLifecycleOwner) { + meetingViewModel.debounceWhiteBoardObserver.observe(viewLifecycleOwner) { if (it.state == State.Started) { addOrRemoveWebView(shouldAddWebView = true) whiteboardView?.show() From 9428a1c3c5f38ad8928d73f1894730768fbadc66 Mon Sep 17 00:00:00 2001 From: Gulzar Date: Fri, 10 May 2024 18:57:07 +0530 Subject: [PATCH 07/14] Update VideoGridFragment.kt --- .../live/hms/roomkit/ui/meeting/videogrid/VideoGridFragment.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/room-kit/src/main/java/live/hms/roomkit/ui/meeting/videogrid/VideoGridFragment.kt b/room-kit/src/main/java/live/hms/roomkit/ui/meeting/videogrid/VideoGridFragment.kt index fc94bafe0..ae8550275 100644 --- a/room-kit/src/main/java/live/hms/roomkit/ui/meeting/videogrid/VideoGridFragment.kt +++ b/room-kit/src/main/java/live/hms/roomkit/ui/meeting/videogrid/VideoGridFragment.kt @@ -87,7 +87,7 @@ class VideoGridFragment : Fragment() { private fun initWhiteBoard() { - meetingViewModel.debounceWhiteBoardObserver.observe(viewLifecycleOwner) { + meetingViewModel.showHideWhiteboardObserver.observe(viewLifecycleOwner) { if (it.state == State.Started) { addOrRemoveWebView(shouldAddWebView = true) whiteboardView?.show() From 3586ad8bdb5ea545f31eaa1bdfb2c0bde85817bd Mon Sep 17 00:00:00 2001 From: Aniket Kadam Date: Wed, 15 May 2024 12:56:52 +0530 Subject: [PATCH 08/14] Add and remove the fragment. Still have an issue with the stream somehow being ended before its started. Signed-off-by: Aniket Kadam --- .../roomkit/ui/meeting/MeetingViewModel.kt | 41 ++++++++++++++----- .../ui/meeting/activespeaker/HlsFragment.kt | 2 +- .../ui/meeting/activespeaker/HlsViewModel.kt | 7 ++-- .../activespeaker/HlsViewModelFactory.kt | 3 +- .../ui/meeting/bottomsheets/StreamEnded.kt | 38 +++++++++++++++++ 5 files changed, 75 insertions(+), 16 deletions(-) diff --git a/room-kit/src/main/java/live/hms/roomkit/ui/meeting/MeetingViewModel.kt b/room-kit/src/main/java/live/hms/roomkit/ui/meeting/MeetingViewModel.kt index 517f7d587..9a314a0b4 100644 --- a/room-kit/src/main/java/live/hms/roomkit/ui/meeting/MeetingViewModel.kt +++ b/room-kit/src/main/java/live/hms/roomkit/ui/meeting/MeetingViewModel.kt @@ -14,10 +14,12 @@ import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.SharedFlow import kotlinx.coroutines.launch +import live.hms.hls_player.HmsHlsPlaybackState import live.hms.hls_player.HmsHlsPlayer import live.hms.roomkit.R import live.hms.roomkit.ui.HMSPrebuiltOptions import live.hms.roomkit.ui.meeting.activespeaker.ActiveSpeakerHandler +import live.hms.roomkit.ui.meeting.bottomsheets.StreamState import live.hms.roomkit.ui.meeting.chat.ChatMessage import live.hms.roomkit.ui.meeting.chat.Recipient import live.hms.roomkit.ui.meeting.participants.ParticipantPreviousRoleChangeUseCase @@ -2562,21 +2564,34 @@ class MeetingViewModel( fun shouldSkipPreview() = prebuiltInfoContainer.shouldSkipPreview() private var playerStarted = false - fun hlsPlayerBeganToPlay() { - val lp = lastStartedPoll - if(lp == null) { - playerStarted = true - return - } + fun hlsPlayerBeganToPlay(hmsHlsPlaybackState: HmsHlsPlaybackState) { + if(hmsHlsPlaybackState == HmsHlsPlaybackState.playing) { + val lp = lastStartedPoll + if (lp == null) { + playerStarted = true + return + } - val currentUnixTimestampInSeconds = (System.currentTimeMillis()/1000L) - val isPollLaunchedGreaterThan20SecondsAgo = currentUnixTimestampInSeconds - lp.startedAt > 20 - if(!playerStarted && isPollLaunchedGreaterThan20SecondsAgo) { + val currentUnixTimestampInSeconds = (System.currentTimeMillis() / 1000L) + val isPollLaunchedGreaterThan20SecondsAgo = + currentUnixTimestampInSeconds - lp.startedAt > 20 + if (!playerStarted && isPollLaunchedGreaterThan20SecondsAgo) { + viewModelScope.launch { + triggerPollsNotification(lp) + } + } + playerStarted = true + logS("Set player started true") + viewModelScope.launch { + _hlsStreamEndedFlow.emit(StreamState.STARTED) + } + } else if (hmsHlsPlaybackState == HmsHlsPlaybackState.stopped) { + playerStarted = false viewModelScope.launch { - triggerPollsNotification(lp) + _hlsStreamEndedFlow.emit(StreamState.ENDED) } + logS("Set player started false") } - playerStarted = true } fun disableNameEdit() = prebuiltOptions?.userName != null @@ -2682,5 +2697,9 @@ class MeetingViewModel( reEnableCaptions = false } } + + private val _hlsStreamEndedFlow = MutableSharedFlow(replay = 0) + val hlsStreamEndedFlow : Flow = _hlsStreamEndedFlow + } diff --git a/room-kit/src/main/java/live/hms/roomkit/ui/meeting/activespeaker/HlsFragment.kt b/room-kit/src/main/java/live/hms/roomkit/ui/meeting/activespeaker/HlsFragment.kt index 95f62ac99..c21ddad65 100644 --- a/room-kit/src/main/java/live/hms/roomkit/ui/meeting/activespeaker/HlsFragment.kt +++ b/room-kit/src/main/java/live/hms/roomkit/ui/meeting/activespeaker/HlsFragment.kt @@ -173,7 +173,7 @@ private const val MILLI_SECONDS_FROM_LIVE = 10_000 } private val hlsViewModel: HlsViewModel by activityViewModels { HlsViewModelFactory(requireActivity().application,args.hlsStreamUrl, meetingViewModel.hmsSDK, - meetingViewModel::hlsPlayerBeganToPlay + { state : HmsHlsPlaybackState -> meetingViewModel.hlsPlayerBeganToPlay(state) } ) { displayHlsCuesUseCase } } private val player by lazy { hlsViewModel.player } diff --git a/room-kit/src/main/java/live/hms/roomkit/ui/meeting/activespeaker/HlsViewModel.kt b/room-kit/src/main/java/live/hms/roomkit/ui/meeting/activespeaker/HlsViewModel.kt index 54d28806f..9a44603e8 100644 --- a/room-kit/src/main/java/live/hms/roomkit/ui/meeting/activespeaker/HlsViewModel.kt +++ b/room-kit/src/main/java/live/hms/roomkit/ui/meeting/activespeaker/HlsViewModel.kt @@ -24,7 +24,7 @@ import live.hms.video.sdk.HMSSDK application: Application, private val hlsStreamUrl : String, private val hmsSdk: HMSSDK, - private val hlsPlayerBeganToPlay : () -> Unit, + private val hlsPlayerBeganToPlay : (HmsHlsPlaybackState) -> Unit, private val displayHlsCuesUseCase : () -> DisplayHlsCuesUseCase ) : AndroidViewModel(application) { val isPlaying = MutableLiveData(true) @@ -88,13 +88,14 @@ import live.hms.video.sdk.HMSSDK // contextSafe { context, activity -> // activity.runOnUiThread { if (state == HmsHlsPlaybackState.playing) { - hlsPlayerBeganToPlay() + hlsPlayerBeganToPlay(state) isPlaying.postValue(true) } else if (state == HmsHlsPlaybackState.stopped) { // Open end stream fragment. + hlsPlayerBeganToPlay(state) streamEndedEvent.postValue(Unit) isPlaying.postValue(false) - } else isPlaying.postValue(true) + } // } // } // Log.d("HMSHLSPLAYER", "From App, playback state: $state") diff --git a/room-kit/src/main/java/live/hms/roomkit/ui/meeting/activespeaker/HlsViewModelFactory.kt b/room-kit/src/main/java/live/hms/roomkit/ui/meeting/activespeaker/HlsViewModelFactory.kt index 07d55b75d..24190f302 100644 --- a/room-kit/src/main/java/live/hms/roomkit/ui/meeting/activespeaker/HlsViewModelFactory.kt +++ b/room-kit/src/main/java/live/hms/roomkit/ui/meeting/activespeaker/HlsViewModelFactory.kt @@ -4,13 +4,14 @@ import android.app.Application import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModelProvider import androidx.media3.common.util.UnstableApi +import live.hms.hls_player.HmsHlsPlaybackState import live.hms.video.sdk.HMSSDK @UnstableApi class HlsViewModelFactory( private val application: Application, private val hlsStreamUrl: String, private val hmsSdk: HMSSDK, - private val hlsPlayerBeganToPlay: () -> Unit, + private val hlsPlayerBeganToPlay: (HmsHlsPlaybackState) -> Unit, private val displayHlsCuesUseCase: () -> DisplayHlsCuesUseCase ) : ViewModelProvider.NewInstanceFactory() { diff --git a/room-kit/src/main/java/live/hms/roomkit/ui/meeting/bottomsheets/StreamEnded.kt b/room-kit/src/main/java/live/hms/roomkit/ui/meeting/bottomsheets/StreamEnded.kt index c8162f9ca..dc53b9fc6 100644 --- a/room-kit/src/main/java/live/hms/roomkit/ui/meeting/bottomsheets/StreamEnded.kt +++ b/room-kit/src/main/java/live/hms/roomkit/ui/meeting/bottomsheets/StreamEnded.kt @@ -4,14 +4,30 @@ import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import androidx.activity.OnBackPressedCallback import androidx.fragment.app.Fragment import androidx.fragment.app.FragmentManager +import androidx.fragment.app.activityViewModels +import androidx.lifecycle.lifecycleScope +import kotlinx.coroutines.launch import live.hms.roomkit.R import live.hms.roomkit.databinding.StreamEndedBinding +import live.hms.roomkit.ui.meeting.MeetingViewModel +import live.hms.roomkit.ui.meeting.MeetingViewModelFactory import live.hms.roomkit.ui.theme.applyTheme +import live.hms.roomkit.util.logS import live.hms.roomkit.util.viewLifecycle +enum class StreamState { + ENDED, + STARTED +} class StreamEnded: Fragment() { + val meetingViewModel : MeetingViewModel by activityViewModels { + MeetingViewModelFactory( + requireActivity().application + ) + } companion object { const val TAG = "StreamEndedFragment" fun launch(fm: FragmentManager) { @@ -34,6 +50,28 @@ class StreamEnded: Fragment() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) binding.applyTheme() + initOnBackPress() + // now we watch something to dismiss the fragment if it needs to be. + lifecycleScope.launch { + meetingViewModel.hlsStreamEndedFlow.collect { + if(it == StreamState.ENDED) { + logS("Removing the fragment") + parentFragmentManager + .beginTransaction() + .remove(this@StreamEnded) + .commitAllowingStateLoss() + } + } + } + } + private fun initOnBackPress() { + requireActivity().onBackPressedDispatcher.addCallback( + viewLifecycleOwner, + object : OnBackPressedCallback(true) { + override fun handleOnBackPressed() { + meetingViewModel.leaveMeeting() + } + }) } } \ No newline at end of file From f5e600854e75d98d072fe21f0c43ba02567fabeb Mon Sep 17 00:00:00 2001 From: Aniket Kadam Date: Wed, 15 May 2024 16:30:20 +0530 Subject: [PATCH 09/14] Fix stream ended to work in case of streams being stopped and started again. Signed-off-by: Aniket Kadam --- app/build.gradle | 4 +-- .../roomkit/ui/meeting/MeetingViewModel.kt | 2 -- .../ui/meeting/activespeaker/HlsFragment.kt | 19 +++++++++---- .../ui/meeting/activespeaker/HlsViewModel.kt | 28 ++++++++----------- .../ui/meeting/bottomsheets/StreamEnded.kt | 7 ++--- 5 files changed, 30 insertions(+), 30 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 0f00e18e7..ea8aaddf7 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -59,10 +59,10 @@ dependencies { implementation 'androidx.constraintlayout:constraintlayout:2.1.4' //100ms.live prebuilt lib - implementation "live.100ms:room-kit:$HMS_ROOM_KIT_VERSION" + implementation project(":room-kit") //100ms noise cancellation dep - def hmsVersion = "2.9.55" + def hmsVersion = "2.9.55-df" implementation "live.100ms:hms-noise-cancellation-android:$hmsVersion" // Navigation diff --git a/room-kit/src/main/java/live/hms/roomkit/ui/meeting/MeetingViewModel.kt b/room-kit/src/main/java/live/hms/roomkit/ui/meeting/MeetingViewModel.kt index 9a314a0b4..3e43ab589 100644 --- a/room-kit/src/main/java/live/hms/roomkit/ui/meeting/MeetingViewModel.kt +++ b/room-kit/src/main/java/live/hms/roomkit/ui/meeting/MeetingViewModel.kt @@ -2581,7 +2581,6 @@ class MeetingViewModel( } } playerStarted = true - logS("Set player started true") viewModelScope.launch { _hlsStreamEndedFlow.emit(StreamState.STARTED) } @@ -2590,7 +2589,6 @@ class MeetingViewModel( viewModelScope.launch { _hlsStreamEndedFlow.emit(StreamState.ENDED) } - logS("Set player started false") } } diff --git a/room-kit/src/main/java/live/hms/roomkit/ui/meeting/activespeaker/HlsFragment.kt b/room-kit/src/main/java/live/hms/roomkit/ui/meeting/activespeaker/HlsFragment.kt index c21ddad65..750e00d21 100644 --- a/room-kit/src/main/java/live/hms/roomkit/ui/meeting/activespeaker/HlsFragment.kt +++ b/room-kit/src/main/java/live/hms/roomkit/ui/meeting/activespeaker/HlsFragment.kt @@ -202,6 +202,9 @@ private const val MILLI_SECONDS_FROM_LIVE = 10_000 private lateinit var composeView: ComposeView + fun playInstead() { + player.play(args.hlsStreamUrl) + } @OptIn(ExperimentalAnimationApi::class) override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? @@ -225,6 +228,7 @@ private const val MILLI_SECONDS_FROM_LIVE = 10_000 override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) hlsViewModel.streamEndedEvent.observe(viewLifecycleOwner) { + player.stop() StreamEnded.launch(parentFragmentManager) } meetingViewModel.broadcastsReceived.observe(viewLifecycleOwner) { @@ -258,9 +262,10 @@ private const val MILLI_SECONDS_FROM_LIVE = 10_000 val progressBarVisibility by hlsViewModel.progressBarVisible.observeAsState() val viewMode by meetingViewModel.state.observeAsState() + val hlsPlayerReady by hlsViewModel.playerReady.observeAsState() // Don't show whole view loading during the time it's disconnected or reconnecting. - if (progressBarVisibility == true || viewMode !is MeetingState.Ongoing) { + if (progressBarVisibility == true || viewMode !is MeetingState.Ongoing || hlsPlayerReady != true) { CircularProgressIndicator( modifier = Modifier .fillMaxSize() @@ -444,7 +449,7 @@ private const val MILLI_SECONDS_FROM_LIVE = 10_000 } - PauseWhenLeaving(player) + PauseWhenLeaving(player, ::playInstead) RemoveStatsWhenPaused(::setPlayerStatsListener, player) } @@ -1418,7 +1423,7 @@ fun HlsChatIcon(chatEnabled: Boolean, unreadMessages :Int?, buttonClicked: () -> } @Composable -fun PauseWhenLeaving(player : HmsHlsPlayer) { +fun PauseWhenLeaving(player : HmsHlsPlayer, playInstead :() -> Unit) { OnLifecycleEvent { _, event -> when(event) { @@ -1427,8 +1432,12 @@ fun PauseWhenLeaving(player : HmsHlsPlayer) { } Lifecycle.Event.ON_RESUME -> { - player.resume() - player.seekToLivePosition() + if(player.getNativePlayer().playbackState == Player.STATE_IDLE) { + playInstead() + } else { + player.resume() + player.seekToLivePosition() + } } else -> {} diff --git a/room-kit/src/main/java/live/hms/roomkit/ui/meeting/activespeaker/HlsViewModel.kt b/room-kit/src/main/java/live/hms/roomkit/ui/meeting/activespeaker/HlsViewModel.kt index 9a44603e8..19296f227 100644 --- a/room-kit/src/main/java/live/hms/roomkit/ui/meeting/activespeaker/HlsViewModel.kt +++ b/room-kit/src/main/java/live/hms/roomkit/ui/meeting/activespeaker/HlsViewModel.kt @@ -2,7 +2,6 @@ package live.hms.roomkit.ui.meeting.activespeaker import android.annotation.SuppressLint import android.app.Application -import android.util.Log import androidx.lifecycle.AndroidViewModel import androidx.lifecycle.MutableLiveData import androidx.lifecycle.map @@ -35,6 +34,7 @@ import live.hms.video.sdk.HMSSDK val behindLiveByLiveData = MutableLiveData("0:0") val streamEndedEvent = SingleLiveEvent() val currentSubtitles = MutableLiveData() + val playerReady = MutableLiveData(false) private var failed = false val player = HmsHlsPlayer(application, hmsSdk).apply { @@ -51,12 +51,12 @@ import live.hms.video.sdk.HMSSDK } } private fun setListeners(player: HmsHlsPlayer) { -// binding.hlsView.player = player.getNativePlayer() player.getNativePlayer().addListener(@UnstableApi object : Player.Listener { override fun onIsPlayingChanged(isPlaying: Boolean) { super.onIsPlayingChanged(isPlaying) if (isPlaying) { videoVisible.postValue(true) + playerReady.postValue(true) } } @@ -79,26 +79,20 @@ import live.hms.video.sdk.HMSSDK player.addPlayerEventListener(object : HmsHlsPlaybackEvents { override fun onPlaybackFailure(error: HmsHlsException) { - Log.d("HMSHLSPLAYER", "From App, error: $error") failed = true } @SuppressLint("UnsafeOptInUsageError") override fun onPlaybackStateChanged(state: HmsHlsPlaybackState) { -// contextSafe { context, activity -> -// activity.runOnUiThread { - if (state == HmsHlsPlaybackState.playing) { - hlsPlayerBeganToPlay(state) - isPlaying.postValue(true) - } else if (state == HmsHlsPlaybackState.stopped) { - // Open end stream fragment. - hlsPlayerBeganToPlay(state) - streamEndedEvent.postValue(Unit) - isPlaying.postValue(false) - } -// } -// } -// Log.d("HMSHLSPLAYER", "From App, playback state: $state") + if (state == HmsHlsPlaybackState.playing) { + hlsPlayerBeganToPlay(state) + isPlaying.postValue(true) + } else if (state == HmsHlsPlaybackState.stopped) { + // Open end stream fragment. + hlsPlayerBeganToPlay(state) + streamEndedEvent.postValue(Unit) + isPlaying.postValue(false) + } } override fun onCue(cue: HmsHlsCue) { diff --git a/room-kit/src/main/java/live/hms/roomkit/ui/meeting/bottomsheets/StreamEnded.kt b/room-kit/src/main/java/live/hms/roomkit/ui/meeting/bottomsheets/StreamEnded.kt index dc53b9fc6..3f8d34195 100644 --- a/room-kit/src/main/java/live/hms/roomkit/ui/meeting/bottomsheets/StreamEnded.kt +++ b/room-kit/src/main/java/live/hms/roomkit/ui/meeting/bottomsheets/StreamEnded.kt @@ -15,7 +15,6 @@ import live.hms.roomkit.databinding.StreamEndedBinding import live.hms.roomkit.ui.meeting.MeetingViewModel import live.hms.roomkit.ui.meeting.MeetingViewModelFactory import live.hms.roomkit.ui.theme.applyTheme -import live.hms.roomkit.util.logS import live.hms.roomkit.util.viewLifecycle enum class StreamState { @@ -33,7 +32,8 @@ class StreamEnded: Fragment() { fun launch(fm: FragmentManager) { fm .beginTransaction() - .add(R.id.fragment_container, StreamEnded()) + // We want the hlsfragment to be stopped entirely so this fragment needs to be replaced not added. + .replace(R.id.fragment_container, StreamEnded()) .commit() } } @@ -54,8 +54,7 @@ class StreamEnded: Fragment() { // now we watch something to dismiss the fragment if it needs to be. lifecycleScope.launch { meetingViewModel.hlsStreamEndedFlow.collect { - if(it == StreamState.ENDED) { - logS("Removing the fragment") + if(it == StreamState.STARTED) { parentFragmentManager .beginTransaction() .remove(this@StreamEnded) From 9ff2b51ae4739ebb0e8bf54fca76468e127ed396 Mon Sep 17 00:00:00 2001 From: Aniket Kadam Date: Wed, 15 May 2024 16:33:06 +0530 Subject: [PATCH 10/14] fix Signed-off-by: Aniket Kadam --- app/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index ea8aaddf7..0f00e18e7 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -59,10 +59,10 @@ dependencies { implementation 'androidx.constraintlayout:constraintlayout:2.1.4' //100ms.live prebuilt lib - implementation project(":room-kit") + implementation "live.100ms:room-kit:$HMS_ROOM_KIT_VERSION" //100ms noise cancellation dep - def hmsVersion = "2.9.55-df" + def hmsVersion = "2.9.55" implementation "live.100ms:hms-noise-cancellation-android:$hmsVersion" // Navigation From f4b8e2dd8146f1904350c32d8d551ac19b59cde8 Mon Sep 17 00:00:00 2001 From: Gulzar Date: Fri, 17 May 2024 17:57:18 +0530 Subject: [PATCH 11/14] Feature/bluetooth names (#714) * added changes * fix * added changes --- app/src/main/AndroidManifest.xml | 3 +- .../live/hms/roomkit/ui/meeting/AudioItem.kt | 99 +++++++++ .../meeting/AudioOutputSwitchBottomSheet.kt | 194 ++++++++---------- .../roomkit/ui/meeting/MeetingViewModel.kt | 2 +- .../res/layout/bottom_sheet_audio_switch.xml | 109 +--------- .../main/res/layout/item_device_detail.xml | 29 +++ 6 files changed, 226 insertions(+), 210 deletions(-) create mode 100644 room-kit/src/main/java/live/hms/roomkit/ui/meeting/AudioItem.kt create mode 100644 room-kit/src/main/res/layout/item_device_detail.xml diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 2326e5b61..e80d69d66 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -6,8 +6,7 @@ + android:name="android.permission.BLUETOOTH" /> diff --git a/room-kit/src/main/java/live/hms/roomkit/ui/meeting/AudioItem.kt b/room-kit/src/main/java/live/hms/roomkit/ui/meeting/AudioItem.kt new file mode 100644 index 000000000..093272aa5 --- /dev/null +++ b/room-kit/src/main/java/live/hms/roomkit/ui/meeting/AudioItem.kt @@ -0,0 +1,99 @@ +package live.hms.roomkit.ui.meeting + +import android.graphics.PorterDuff +import android.os.Build +import android.view.View +import androidx.annotation.DrawableRes +import androidx.core.text.bold +import androidx.core.text.buildSpannedString +import com.xwray.groupie.viewbinding.BindableItem +import live.hms.roomkit.R +import live.hms.roomkit.databinding.ItemDeviceDetailBinding +import live.hms.roomkit.drawableEnd +import live.hms.roomkit.drawableStart +import live.hms.roomkit.setDrawables +import live.hms.roomkit.setOnSingleClickListener +import live.hms.roomkit.ui.theme.HMSPrebuiltTheme +import live.hms.roomkit.ui.theme.getColorOrDefault +import live.hms.video.audio.HMSAudioManager +import live.hms.video.audio.manager.AudioManagerUtil +import kotlin.math.roundToInt + +class AudioItem( + private var title: String, + private var subTitle: String? = null, + private val isSelected: Boolean, + @DrawableRes private val drawableRes: Int, + val type: HMSAudioManager.AudioDevice = HMSAudioManager.AudioDevice.AUTOMATIC, + val id: Int? = null, + private val onClick: (HMSAudioManager.AudioDevice, Int?) -> Unit, + + ) : BindableItem() { + + + override fun bind(binding: ItemDeviceDetailBinding, position: Int) { + if (isSelected) binding.audioText.setDrawables( + end = binding.audioText.context?.getDrawable( + R.drawable.tick + ) + ) + else binding.audioText.setDrawables(end = null) + + binding.audioText.setDrawables( + start = binding.audioText.context?.getDrawable( + drawableRes + ) + ) + + + binding.audioText.text = buildSpannedString { + append(title) + if (subTitle.isNullOrEmpty().not() && type.toString() == AudioManagerUtil.AudioDevice.BLUETOOTH.toString()) { + bold { append(" ( ${subTitle.orEmpty()} )") } + } + } + + binding.root.setOnSingleClickListener { + onClick.invoke(type, id) + } + + + binding.audioText.setTextColor( + getColorOrDefault( + HMSPrebuiltTheme.getColours()?.onSurfaceHigh, + HMSPrebuiltTheme.getDefaults().onsurface_high_emp + ) + ) + + binding.audioText.drawableEnd?.setTint( + getColorOrDefault( + HMSPrebuiltTheme.getColours()?.onSurfaceHigh, + HMSPrebuiltTheme.getDefaults().onsurface_high_emp + ) + ) + + binding.audioText.drawableStart?.setTint( + getColorOrDefault( + HMSPrebuiltTheme.getColours()?.onSurfaceHigh, + HMSPrebuiltTheme.getDefaults().onsurface_high_emp + ) + ) + + + + + binding.border4.setBackgroundColor( + getColorOrDefault( + HMSPrebuiltTheme.getColours()?.borderDefault, + HMSPrebuiltTheme.getDefaults().border_bright + ) + ) + } + + + override fun getLayout(): Int = R.layout.item_device_detail + + + override fun initializeViewBinding(view: View) = ItemDeviceDetailBinding.bind(view) + +} \ No newline at end of file diff --git a/room-kit/src/main/java/live/hms/roomkit/ui/meeting/AudioOutputSwitchBottomSheet.kt b/room-kit/src/main/java/live/hms/roomkit/ui/meeting/AudioOutputSwitchBottomSheet.kt index 528ab7e6a..5e4b3da4b 100644 --- a/room-kit/src/main/java/live/hms/roomkit/ui/meeting/AudioOutputSwitchBottomSheet.kt +++ b/room-kit/src/main/java/live/hms/roomkit/ui/meeting/AudioOutputSwitchBottomSheet.kt @@ -6,9 +6,11 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.fragment.app.activityViewModels +import androidx.recyclerview.widget.LinearLayoutManager import com.google.android.material.bottomsheet.BottomSheetBehavior import com.google.android.material.bottomsheet.BottomSheetDialog import com.google.android.material.bottomsheet.BottomSheetDialogFragment +import com.xwray.groupie.GroupieAdapter import live.hms.roomkit.R import live.hms.roomkit.databinding.BottomSheetAudioSwitchBinding import live.hms.roomkit.drawableEnd @@ -26,6 +28,8 @@ class AudioOutputSwitchBottomSheet( private var binding by viewLifecycle() + private val audioDeviceAdapter = GroupieAdapter() + private val meetingViewModel: MeetingViewModel by activityViewModels { MeetingViewModelFactory( @@ -54,38 +58,39 @@ class AudioOutputSwitchBottomSheet( sheet.behavior.state = BottomSheetBehavior.STATE_EXPANDED } - binding.root.background = resources.getDrawable(R.drawable.gray_shape_round_dialog) - .apply { - val color = getColorOrDefault( - HMSPrebuiltTheme.getColours()?.backgroundDefault, - HMSPrebuiltTheme.getDefaults().background_default) - setColorFilter(color, PorterDuff.Mode.ADD); - } - - - var btnArray = arrayOf( - binding.muteBtn, - binding.speakerBtn, - binding.wiredBtn, - binding.bluetoothBtn, - binding.earpieceBtn, - binding.audioOt + binding.audioOt.drawableStart?.setTint( + getColorOrDefault( + HMSPrebuiltTheme.getColours()?.onSurfaceHigh, + HMSPrebuiltTheme.getDefaults().onsurface_high_emp + ) ) - val borders = arrayOf( - binding.border1, binding.border2, binding.border3, binding.border4, binding.border5 + binding.audioOt.setTextColor( + getColorOrDefault( + HMSPrebuiltTheme.getColours()?.onSurfaceHigh, + HMSPrebuiltTheme.getDefaults().onsurface_high_emp + ) ) - borders.forEach { - it.setBackgroundColor( - getColorOrDefault( - HMSPrebuiltTheme.getColours()?.borderDefault, - HMSPrebuiltTheme.getDefaults().border_bright - ) + + + + binding.border5.setBackgroundColor( + getColorOrDefault( + HMSPrebuiltTheme.getColours()?.borderDefault, + HMSPrebuiltTheme.getDefaults().border_bright ) - } + ) + binding.root.background = + binding.root.context.resources.getDrawable(R.drawable.gray_shape_round_dialog).apply { + val color = getColorOrDefault( + HMSPrebuiltTheme.getColours()?.backgroundDefault, + HMSPrebuiltTheme.getDefaults().background_default + ) + setColorFilter(color, PorterDuff.Mode.ADD); + } binding.closeBtn.drawable.setTint( getColorOrDefault( @@ -93,116 +98,99 @@ class AudioOutputSwitchBottomSheet( HMSPrebuiltTheme.getDefaults().onsurface_high_emp ) ) - binding.closeBtn.setOnClickListener { dismissAllowingStateLoss() } - val devicesList = meetingViewModel.hmsSDK.getAudioDevicesList() + audioDeviceAdapter.clear() + val devicesList = meetingViewModel.hmsSDK.getAudioDevicesInfoList() + + //skips for HLS playback + val showAudioOption = meetingViewModel.hmsSDK.getRoom()?.localPeer?.isWebrtcPeer() + var isMute: Boolean = false + var selectedDeviceType: AudioDevice? = null if (meetingViewModel.isPeerAudioEnabled().not()) { - binding.muteBtn.setDrawables(end = context?.getDrawable(R.drawable.tick)) + isMute = true } else { - meetingViewModel.hmsSDK.getAudioOutputRouteType().let { - when (it) { - AudioDevice.BLUETOOTH -> { - binding.bluetoothBtn.setDrawables(end = context?.getDrawable(R.drawable.tick)) - } - - AudioDevice.SPEAKER_PHONE -> { - binding.speakerBtn.setDrawables(end = context?.getDrawable(R.drawable.tick)) - } - - AudioDevice.EARPIECE -> { - binding.earpieceBtn.setDrawables(end = context?.getDrawable(R.drawable.tick)) - } - - AudioDevice.WIRED_HEADSET -> { - binding.wiredBtn.setDrawables(end = context?.getDrawable(R.drawable.tick)) - } - - else -> { - binding.muteBtn.setDrawables(end = context?.getDrawable(R.drawable.tick)) - } - } - } + selectedDeviceType = meetingViewModel.hmsSDK.getAudioOutputRouteType() } - btnArray.forEach { - it.setTextColor( - getColorOrDefault( - HMSPrebuiltTheme.getColours()?.onSurfaceHigh, - HMSPrebuiltTheme.getDefaults().onsurface_high_emp + if (showAudioOption == true) { + for (deviceInfo in devicesList) { + + //backward compatibility handling + val isSelected = (selectedDeviceType == deviceInfo.type) + audioDeviceAdapter.add( + AudioItem( + title = capitalizeAndReplaceUnderscore(deviceInfo.type.name), + subTitle= deviceInfo.name.orEmpty(), + isSelected = isSelected, + type = deviceInfo.type, + drawableRes = getDrawableBasedOnDeviceType(deviceInfo.type), + onClick = { type, id -> + setAudioType(type) + }) ) - ) - it.drawableEnd?.setTint( - getColorOrDefault( - HMSPrebuiltTheme.getColours()?.onSurfaceHigh, - HMSPrebuiltTheme.getDefaults().onsurface_high_emp - ) - ) - it.drawableStart?.setTint( - getColorOrDefault( - HMSPrebuiltTheme.getColours()?.onSurfaceHigh, - HMSPrebuiltTheme.getDefaults().onsurface_high_emp - ) - ) + } } - if (devicesList.contains(AudioDevice.BLUETOOTH)) { - binding.bluetoothBtn.visibility = View.VISIBLE - } - if (devicesList.contains(AudioDevice.WIRED_HEADSET)) { - binding.wiredBtn.visibility = View.VISIBLE - } + audioDeviceAdapter.add( + AudioItem(title = "Mute", + isSelected = isMute, + drawableRes = R.drawable.ic_volume_off_24, + onClick = { type, id -> + meetingViewModel.setPeerAudioEnabled(false) + onOptionItemClicked?.invoke(null, true) + dismiss() + }) + ) - if (devicesList.contains(AudioDevice.EARPIECE)) { - binding.earpieceBtn.visibility = View.VISIBLE - } - if (devicesList.contains(AudioDevice.SPEAKER_PHONE)) { - binding.speakerBtn.visibility = View.VISIBLE - } - if (meetingViewModel.hmsSDK.getRoom()?.localPeer?.isWebrtcPeer() != true) { - binding.wiredBtn.visibility = View.GONE - binding.bluetoothBtn.visibility = View.GONE - binding.earpieceBtn.visibility = View.GONE - binding.muteBtn.visibility = View.GONE - } else { - binding.muteBtn.visibility = View.VISIBLE + binding.deviceList.apply { + layoutManager = LinearLayoutManager(requireContext()) + adapter = audioDeviceAdapter } + } - - - - binding.speakerBtn.setOnClickListener { - setAudioType(AudioDevice.SPEAKER_PHONE) + fun getDrawableBasedOnDeviceType(device: AudioDevice): Int = when (device) { + AudioDevice.BLUETOOTH -> { + R.drawable.bt } - binding.wiredBtn.setOnClickListener { - setAudioType(AudioDevice.WIRED_HEADSET) + AudioDevice.SPEAKER_PHONE -> { + R.drawable.ic_icon_speaker } - binding.bluetoothBtn.setOnClickListener { - setAudioType(AudioDevice.BLUETOOTH) + AudioDevice.EARPIECE -> { + R.drawable.phone } - binding.earpieceBtn.setOnClickListener { - setAudioType(AudioDevice.EARPIECE) + AudioDevice.WIRED_HEADSET -> { + R.drawable.wired } - binding.muteBtn.setOnClickListener { - meetingViewModel.setPeerAudioEnabled(false) - onOptionItemClicked?.invoke(null, true) - dismiss() + AudioDevice.AUTOMATIC -> R.drawable.ic_icon_speaker + } + + + fun capitalizeAndReplaceUnderscore(input: String): String { + if (input.isEmpty()) { + return "" } + + // Capitalize the first character + val capitalized = input.toLowerCase().replaceFirstChar { it.uppercase() } + + // Replace underscores with spaces + return capitalized.replace('_', ' ') } override fun getTheme(): Int { diff --git a/room-kit/src/main/java/live/hms/roomkit/ui/meeting/MeetingViewModel.kt b/room-kit/src/main/java/live/hms/roomkit/ui/meeting/MeetingViewModel.kt index 3e43ab589..e586c5295 100644 --- a/room-kit/src/main/java/live/hms/roomkit/ui/meeting/MeetingViewModel.kt +++ b/room-kit/src/main/java/live/hms/roomkit/ui/meeting/MeetingViewModel.kt @@ -326,7 +326,7 @@ class MeetingViewModel( } - }, 30) + }) } } diff --git a/room-kit/src/main/res/layout/bottom_sheet_audio_switch.xml b/room-kit/src/main/res/layout/bottom_sheet_audio_switch.xml index ca67694bd..2bb479acd 100644 --- a/room-kit/src/main/res/layout/bottom_sheet_audio_switch.xml +++ b/room-kit/src/main/res/layout/bottom_sheet_audio_switch.xml @@ -53,110 +53,11 @@ android:layout_marginHorizontal="16dp" android:background="@drawable/gray_line_vertical_divider" /> - - - - - - - - - - - - - - - - - - - - - - - - - - - + diff --git a/room-kit/src/main/res/layout/item_device_detail.xml b/room-kit/src/main/res/layout/item_device_detail.xml new file mode 100644 index 000000000..88c4dd4dd --- /dev/null +++ b/room-kit/src/main/res/layout/item_device_detail.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + \ No newline at end of file From 739df5da37bf97e02c7a135621843acb583a5753 Mon Sep 17 00:00:00 2001 From: Aniket Kadam Date: Fri, 17 May 2024 18:10:53 +0530 Subject: [PATCH 12/14] Update room kit Signed-off-by: Aniket Kadam --- gradle.properties | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle.properties b/gradle.properties index 8c8acdb01..ae3bbcab9 100644 --- a/gradle.properties +++ b/gradle.properties @@ -22,5 +22,5 @@ kotlin.code.style=official 100MS_APP_VERSION_CODE=372 100MS_APP_VERSION_NAME=5.0.6 hmsRoomKitGroup=live.100ms -HMS_ROOM_KIT_VERSION=1.2.11 +HMS_ROOM_KIT_VERSION=1.2.12 android.suppressUnsupportedCompileSdk=33 From 22d21089a09a4affe6f911028c4ce5207ec87217 Mon Sep 17 00:00:00 2001 From: Aniket Kadam Date: Fri, 17 May 2024 18:11:59 +0530 Subject: [PATCH 13/14] Update app version and code Signed-off-by: Aniket Kadam --- gradle.properties | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gradle.properties b/gradle.properties index ae3bbcab9..15a0860a1 100644 --- a/gradle.properties +++ b/gradle.properties @@ -19,8 +19,8 @@ android.useAndroidX=true android.enableJetifier=true # Kotlin code style for this project: "official" or "obsolete": kotlin.code.style=official -100MS_APP_VERSION_CODE=372 -100MS_APP_VERSION_NAME=5.0.6 +100MS_APP_VERSION_CODE=373 +100MS_APP_VERSION_NAME=5.0.7 hmsRoomKitGroup=live.100ms HMS_ROOM_KIT_VERSION=1.2.12 android.suppressUnsupportedCompileSdk=33 From 153f20f1dd314d3bde214ef152fc36e5f94c81f1 Mon Sep 17 00:00:00 2001 From: Aniket Kadam Date: Fri, 17 May 2024 18:12:44 +0530 Subject: [PATCH 14/14] Update sdk version Signed-off-by: Aniket Kadam --- app/build.gradle | 2 +- room-kit/build.gradle | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 0f00e18e7..ad5128ac2 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -62,7 +62,7 @@ dependencies { implementation "live.100ms:room-kit:$HMS_ROOM_KIT_VERSION" //100ms noise cancellation dep - def hmsVersion = "2.9.55" + def hmsVersion = "2.9.57" implementation "live.100ms:hms-noise-cancellation-android:$hmsVersion" // Navigation diff --git a/room-kit/build.gradle b/room-kit/build.gradle index 6a99c222c..6d4ac5ca1 100644 --- a/room-kit/build.gradle +++ b/room-kit/build.gradle @@ -72,7 +72,7 @@ dependencies { implementation 'com.google.android.material:material:1.10.0' implementation 'androidx.constraintlayout:constraintlayout:2.1.4' implementation 'androidx.percentlayout:percentlayout:1.0.0' - def hmsVersion = "2.9.55" + def hmsVersion = "2.9.57" implementation "com.otaliastudios:zoomlayout:1.9.0" // To add dependencies of specific module implementation "live.100ms:android-sdk:$hmsVersion"