Skip to content

Commit

Permalink
Merge pull request #74 from ciscoRankush/master
Browse files Browse the repository at this point in the history
Release 3.11.0
  • Loading branch information
knamoach authored Feb 13, 2024
2 parents 740d2b9 + bfe80ed commit bd8568c
Show file tree
Hide file tree
Showing 16 changed files with 491 additions and 28 deletions.
17 changes: 11 additions & 6 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ android {
applicationId "com.cisco.sdk_android"
minSdkVersion Versions.minSdk
targetSdkVersion Versions.targetSdk
versionCode 3100100
versionName "3.10.1"
versionCode 3110000
versionName "3.11.0"

testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"

Expand Down Expand Up @@ -63,6 +63,11 @@ android {
buildConfigField "String", "SCOPE", "${SCOPE}"
}

packagingOptions {
jniLibs {
pickFirsts += ['lib/armeabi-v7a/libc++_shared.so', 'lib/arm64-v8a/libc++_shared.so', 'lib/x86/libc++_shared.so', 'lib/x86_64/libc++_shared.so']
}
}
buildTypes {
release {
minifyEnabled true
Expand Down Expand Up @@ -114,10 +119,10 @@ android {

dependencies {

//At a time only one WebexSDK should be used.
implementation 'com.ciscowebex:webexsdk:3.10.1' // For full flavor
//implementation 'com.ciscowebex:webexsdk-wxc:3.10.1' //For webexCalling flavor
//implementation 'com.ciscowebex:webexsdk-meeting:3.10.1' // For meeting flavor
//At a time only one WebexSDK should be used.
implementation 'com.ciscowebex:webexsdk:3.11.0' // For full flavor
//implementation 'com.ciscowebex:webexsdk-wxc:3.11.0' //For webexCalling flavor
//implementation 'com.ciscowebex:webexsdk-meeting:3.11.0' // For meeting flavor

implementation fileTree(dir: "libs", include: ["*.jar"])
implementation Dependencies.kotlinStdLib
Expand Down
5 changes: 4 additions & 1 deletion app/proguard-rules.pro
Original file line number Diff line number Diff line change
Expand Up @@ -117,4 +117,7 @@

-keep enum com.ciscowebex.androidsdk.utils.internal.NetTypes{
*;
}
}
-keep class com.cisco.newb.** {
*;
}
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,8 @@ class WebexRepository(val webex: Webex) : WebexUCLoginDelegate {
InCorrectPasswordWithCaptcha,
InCorrectPasswordOrHostKey,
InCorrectPasswordOrHostKeyWithCaptcha,
WrongApiCalled
WrongApiCalled,
CannotStartInstantMeeting
}

enum class CalendarMeetingEvent {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import com.ciscowebex.androidsdk.kitchensink.firebase.RegisterTokenService
import com.ciscowebex.androidsdk.kitchensink.person.PersonModel
import com.ciscowebex.androidsdk.CompletionHandler
import com.ciscowebex.androidsdk.WebexError
import com.ciscowebex.androidsdk.annotation.renderer.LiveAnnotationRenderer
import com.google.android.gms.tasks.OnCompleteListener
import com.google.android.gms.tasks.Task
import com.google.firebase.messaging.FirebaseMessaging
Expand All @@ -34,6 +35,7 @@ import com.ciscowebex.androidsdk.phone.CallMembership
import com.ciscowebex.androidsdk.phone.Phone
import com.ciscowebex.androidsdk.phone.CallAssociationType
import com.ciscowebex.androidsdk.phone.AdvancedSetting
import com.ciscowebex.androidsdk.phone.MakeHostError
import com.ciscowebex.androidsdk.phone.AuxStream
import com.ciscowebex.androidsdk.phone.VirtualBackground
import com.ciscowebex.androidsdk.phone.CameraExposureISO
Expand All @@ -44,10 +46,14 @@ import com.ciscowebex.androidsdk.phone.MediaStreamQuality
import com.ciscowebex.androidsdk.phone.BreakoutSession
import com.ciscowebex.androidsdk.phone.Breakout
import com.ciscowebex.androidsdk.phone.DirectTransferResult
import com.ciscowebex.androidsdk.phone.InviteParticipantError
import com.ciscowebex.androidsdk.phone.SwitchToAudioVideoCallResult
import com.ciscowebex.androidsdk.phone.PhoneConnectionResult
import com.ciscowebex.androidsdk.phone.ReceivingNoiseInfo
import com.ciscowebex.androidsdk.phone.ReceivingNoiseRemovalEnableResult
import com.ciscowebex.androidsdk.phone.ReclaimHostError
import com.ciscowebex.androidsdk.phone.annotation.LiveAnnotationListener
import com.ciscowebex.androidsdk.phone.annotation.LiveAnnotationsPolicy
import com.ciscowebex.androidsdk.phone.closedCaptions.CaptionItem
import com.ciscowebex.androidsdk.phone.closedCaptions.ClosedCaptionsInfo
import com.google.firebase.installations.FirebaseInstallations
Expand Down Expand Up @@ -98,6 +104,14 @@ class WebexViewModel(val webex: Webex, val repository: WebexRepository) : BaseVi
private val _initialSpacesSyncCompletedLiveData = MutableLiveData<Boolean>()
val initialSpacesSyncCompletedLiveData: LiveData<Boolean> = _initialSpacesSyncCompletedLiveData

private val _annotationEvent = MutableLiveData<AnnotationEvent>()
val annotationEvent: LiveData<AnnotationEvent> get() = _annotationEvent
sealed class AnnotationEvent {
data class PERMISSION_ASK(val personId: String) : AnnotationEvent()
data class PERMISSION_EXPIRED(val personId: String) : AnnotationEvent()
}


var selfPersonId: String? = null
var compositedLayoutState = MediaOption.CompositedVideoLayout.NOT_SUPPORTED

Expand Down Expand Up @@ -403,6 +417,9 @@ class WebexViewModel(val webex: Webex, val repository: WebexRepository) : BaseVi
WebexError.ErrorCode.INVALID_PASSWORD_OR_HOST_KEY_WITH_CAPTCHA.code -> {
_callingLiveData.postValue(WebexRepository.CallLiveData(WebexRepository.CallEvent.InCorrectPasswordOrHostKeyWithCaptcha, null, error.data as Phone.Captcha))
}
WebexError.ErrorCode.CANNOT_START_INSTANT_MEETING.code -> {
_callingLiveData.postValue(WebexRepository.CallLiveData(WebexRepository.CallEvent.CannotStartInstantMeeting, null, null, result.error?.errorMessage))
}
else -> {
_callingLiveData.postValue(WebexRepository.CallLiveData(WebexRepository.CallEvent.DialFailed, null, null, result.error?.errorMessage))
}
Expand Down Expand Up @@ -463,6 +480,7 @@ class WebexViewModel(val webex: Webex, val repository: WebexRepository) : BaseVi
override fun onDisconnected(event: CallObserver.CallDisconnectedEvent?) {
Log.d(tag, "CallObserver onDisconnected event: ${this@WebexViewModel} $callObserverInterface $event")
callObserverInterface?.onDisconnected(call, event)
annotationRenderer?.stopRendering()
}

override fun onInfoChanged(call: Call?) {
Expand Down Expand Up @@ -621,15 +639,22 @@ class WebexViewModel(val webex: Webex, val repository: WebexRepository) : BaseVi
}

fun startShare(callId: String, shareConfig: ShareConfig?) {
getCall(callId)?.startSharing(CompletionHandler { result ->
_startShareLiveData.postValue(result.isSuccessful)
}, shareConfig)
val call = getCall(callId)
call?.let {
it.startSharing(CompletionHandler { result ->
_startShareLiveData.postValue(result.isSuccessful)

}, shareConfig)
}
}

fun startShare(callId: String, notification: Notification?, notificationId: Int, shareConfig: ShareConfig?) {
getCall(callId)?.startSharing(notification, notificationId, CompletionHandler { result ->
_startShareLiveData.postValue(result.isSuccessful)
}, shareConfig)
val call = getCall(callId)
call?.let {
it.startSharing(notification, notificationId, CompletionHandler { result ->
_startShareLiveData.postValue(result.isSuccessful)
}, shareConfig)
}
}

fun setSendingSharing(callId: String, value: Boolean) {
Expand All @@ -642,6 +667,80 @@ class WebexViewModel(val webex: Webex, val repository: WebexRepository) : BaseVi
})
}

private var annotationRenderer: LiveAnnotationRenderer? = null
fun initalizeAnnotations(renderer: LiveAnnotationRenderer) {
getCall(currentCallId.orEmpty())?.getLiveAnnotationHandle()?.let {annotations->

annotations.setLiveAnnotationsPolicy(LiveAnnotationsPolicy.NeedAskForAnnotate){
if (it.isSuccessful) {
Log.d(tag, "setLiveAnnotationsPolicy successful")
} else {
Log.d(tag, "setLiveAnnotationsPolicy error: ${it.error?.errorMessage}")
}
}

annotations.setLiveAnnotationListener(object : LiveAnnotationListener {
override fun onLiveAnnotationRequestReceived(personId: String) {
_annotationEvent.postValue(AnnotationEvent.PERMISSION_ASK(personId))
}

override fun onLiveAnnotationRequestExpired(personId: String) {
_annotationEvent.postValue(AnnotationEvent.PERMISSION_EXPIRED(personId))
}

override fun onLiveAnnotationsStarted() {
annotationRenderer = renderer.apply {
setAnnotationRendererCallback(object : LiveAnnotationRenderer.LiveAnnotationRendererCallback {
override fun onAnnotationRenderingReady() {
Log.d(tag, "onAnnotationRenderingReady")
}

override fun onAnnotationRenderingStopped() {
Log.d(tag, "onAnnotationRenderingStopped")
getCall(currentCallId.orEmpty())?.getLiveAnnotationHandle()?.stopLiveAnnotations()
annotationRenderer = null
}
})
startRendering()
}
}

override fun onLiveAnnotationDataArrived(data: String) {
annotationRenderer?.renderData(data)
}

override fun onLiveAnnotationsStopped() {
annotationRenderer?.stopRendering()
}

})
}
}

fun handleAnnotationPermission(grant: Boolean, personId: String) {
getCall(currentCallId.orEmpty())?.getLiveAnnotationHandle()?.respondToLiveAnnotationRequest(personId, grant) {
if (it.isSuccessful) {
Log.d(tag, "permission handled")
} else {
Log.d(tag, "permission error: ${it.error?.errorMessage}")
}
}
}

fun getCurrentLiveAnnotationPolicy(): LiveAnnotationsPolicy? {
return getCall(currentCallId.orEmpty())?.getLiveAnnotationHandle()?.getLiveAnnotationsPolicy()
}

fun setLiveAnnotationPolicy(policy: LiveAnnotationsPolicy) {
getCall(currentCallId.orEmpty())?.getLiveAnnotationHandle()?.setLiveAnnotationsPolicy(policy) {
if (it.isSuccessful) {
Log.d(tag, "setLiveAnnotationsPolicy successful")
} else {
Log.d(tag, "setLiveAnnotationsPolicy error: ${it.error?.errorMessage}")
}
}
}

fun sendFeedback(callId: String, rating: Int, comment: String) {
getCall(callId)?.sendFeedback(rating, comment)
}
Expand Down Expand Up @@ -1268,6 +1367,30 @@ class WebexViewModel(val webex: Webex, val repository: WebexRepository) : BaseVi
return webex.phone.getCallingType()
}

fun makeHost(participantId: String, handler: CompletionHandler<MakeHostError>) {
getCall(currentCallId.orEmpty())?.makeHost(participantId) { result ->
if (result.isSuccessful) {
Log.d(tag, "Make host successful")
handler.onComplete(ResultImpl.success())
} else {
Log.d(tag, "Make host failed")
handler.onComplete(ResultImpl.error(result.error?.errorMessage))
}
}
}

fun reclaimHost(hostKey:String, handler: CompletionHandler<ReclaimHostError>) {
getCall(currentCallId.orEmpty())?.reclaimHost(hostKey) { result ->
if (result.isSuccessful) {
Log.d(tag, "reclaimHost successful")
handler.onComplete(ResultImpl.success())
} else {
Log.d(tag, "reclaimHost failed")
handler.onComplete(ResultImpl.error(result.error?.errorMessage))
}
}
}

fun setOnInitialSpacesSyncCompletedListener() {
repository.setOnInitialSpacesSyncCompletedListener() {
_initialSpacesSyncCompletedLiveData.postValue(true)
Expand All @@ -1294,6 +1417,18 @@ class WebexViewModel(val webex: Webex, val repository: WebexRepository) : BaseVi
return getCall(currentCallId.orEmpty())?.isVideoEnabled() ?: false
}

fun inviteParticipant(invitee: String, callback: CompletionHandler<InviteParticipantError>) {
getCall(currentCallId.orEmpty())?.inviteParticipant(invitee) { result ->
if (result.isSuccessful) {
Log.d(tag, "InviteParticipant successful")
callback.onComplete(ResultImpl.success())
} else {
Log.d(tag, "InviteParticipant failed")
callback.onComplete(ResultImpl.error(result.error?.errorMessage))
}
}
}

fun cleanup() {
repository.removeIncomingCallListener("viewmodel"+this)
for (entry in callObserverMap.entries.iterator()) {
Expand All @@ -1317,4 +1452,5 @@ class WebexViewModel(val webex: Webex, val repository: WebexRepository) : BaseVi
writer.println("******************")
repository.printObservers(writer)
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ class CallBottomSheetFragment(val showIncomingCallsClickListener: (Call?) -> Uni
val cameraOptionsClickListener: (Call?) -> Unit,
val multiStreamOptionsClickListener: (Call?) -> Unit,
val sendDTMFClickListener: (Call?) -> Unit,
val claimHostClickListener: () -> Unit,
val showBreakoutSessions: () -> Unit,
val closedCaptionOptions: (Call?) -> Unit): BottomSheetDialogFragment() {
companion object {
Expand Down Expand Up @@ -183,6 +184,11 @@ class CallBottomSheetFragment(val showIncomingCallsClickListener: (Call?) -> Uni
transcriptionClickListener(call)
}

claimHost.setOnClickListener {
dismiss()
claimHostClickListener()
}

showIncomingCall.setOnClickListener {
dismiss()
showIncomingCallsClickListener(call)
Expand Down
Loading

0 comments on commit bd8568c

Please sign in to comment.