Skip to content

Commit 7fc64c2

Browse files
committed
Pull request #473: MCA-4335 Various fixes and customization improvement in InfobipRtcUi
Merge in MML/infobip-mobile-messaging-android from jdzubak-MCA-4335-rtcui-fixes-and-improvements to master Squashed commit of the following: commit 343510896ee47ce3d881aca7d7a12bfd22b05563 Author: Jakub Dzubak <Jakub.Dzubak@infobip.com> Date: Mon Dec 9 08:32:36 2024 +0100 MCA-4335 Various fixes and customization improvement in InfobipRtcUi commit 0182e3cb5c06dd3624a7f60af3e08a48ebde19c6 Author: Jakub Dzubak <Jakub.Dzubak@infobip.com> Date: Fri Dec 6 15:04:06 2024 +0100 MCA-4335 Various fixes and customization improvement in InfobipRtcUi
1 parent 73d7ead commit 7fc64c2

26 files changed

+383
-216
lines changed

infobip-mobile-messaging-android-chat-sdk/src/main/java/org/infobip/mobile/messaging/chat/attachments/InAppChatAttachmentHelper.java

+5-5
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,6 @@
1111
import android.provider.MediaStore;
1212
import android.provider.OpenableColumns;
1313

14-
import androidx.annotation.Nullable;
15-
import androidx.annotation.RequiresApi;
16-
import androidx.fragment.app.FragmentActivity;
17-
1814
import org.infobip.mobile.messaging.logging.MobileMessagingLogger;
1915
import org.infobip.mobile.messaging.mobileapi.InternalSdkError;
2016
import org.infobip.mobile.messaging.util.DateTimeUtil;
@@ -23,6 +19,10 @@
2319
import java.io.File;
2420
import java.util.Date;
2521

22+
import androidx.annotation.Nullable;
23+
import androidx.annotation.RequiresApi;
24+
import androidx.fragment.app.FragmentActivity;
25+
2626
public class InAppChatAttachmentHelper {
2727
private static final String JPEG_FILE_PREFIX = "IMG_";
2828
private static final String JPEG_FILE_SUFFIX = ".jpg";
@@ -169,6 +169,6 @@ private static Uri getUriFromMediaStoreURI(Uri mediaStoreUri, FragmentActivity a
169169
public interface InAppChatAttachmentHelperListener {
170170
void onAttachmentCreated(InAppChatMobileAttachment attachment);
171171

172-
void onError(Context context, InternalSdkError.InternalSdkException exception);
172+
void onError(Context context, Exception exception);
173173
}
174174
}

infobip-mobile-messaging-android-chat-sdk/src/main/java/org/infobip/mobile/messaging/chat/view/InAppChatFragment.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -736,7 +736,7 @@ class InAppChatFragment : Fragment(), InAppChatFragmentActivityResultDelegate.Re
736736

737737
override fun onError(
738738
context: Context?,
739-
exception: InternalSdkError.InternalSdkException?
739+
exception: Exception?
740740
) {
741741
if (exception!!.message == InternalSdkError.ERROR_ATTACHMENT_MAX_SIZE_EXCEEDED.get()) {
742742
MobileMessagingLogger.e(
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
package org.infobip.mobile.messaging.chat.view.styles
22

33
data class InAppChatTheme @JvmOverloads constructor(
4-
val chatToolbarStyle: InAppChatToolbarStyle = InAppChatToolbarStyle(),
5-
val attachmentToolbarStyle: InAppChatToolbarStyle = InAppChatToolbarStyle(),
6-
val chatStyle: InAppChatStyle = InAppChatStyle(),
7-
val chatInputViewStyle: InAppChatInputViewStyle = InAppChatInputViewStyle(),
4+
val chatToolbarStyle: InAppChatToolbarStyle = InAppChatToolbarStyle(),
5+
val attachmentToolbarStyle: InAppChatToolbarStyle = InAppChatToolbarStyle(),
6+
val chatStyle: InAppChatStyle = InAppChatStyle(),
7+
val chatInputViewStyle: InAppChatInputViewStyle = InAppChatInputViewStyle(),
88
)

infobip-rtc-ui/src/main/java/com/infobip/webrtc/ui/InfobipRtcUi.kt

+2-2
Original file line numberDiff line numberDiff line change
@@ -349,8 +349,8 @@ interface InfobipRtcUi {
349349
* 3. Default [InfobipRtcUi] style defined by InfobipRtcUi library
350350
*
351351
* Final value for every theme attribute is evaluated separately.
352-
* It means you can define [InfobipRtcUiTheme.incomingCallMessageStyle] in runtime, colors in xml and skip icons.
353-
* Library will use [InfobipRtcUiTheme.incomingCallMessageStyle] you defined in runtime, colors you defined in xml and default icons provided by library itself.
352+
* It means you can define [InfobipRtcUiTheme.incomingCallScreenStyle] in runtime, colors in xml and skip icons.
353+
* Library will use [InfobipRtcUiTheme.incomingCallScreenStyle] you defined in runtime, colors you defined in xml and default icons provided by library itself.
354354
*
355355
* @param theme data object holding all theme attributes
356356
*/

infobip-rtc-ui/src/main/java/com/infobip/webrtc/ui/internal/core/Cache.kt

+9-7
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ import com.infobip.webrtc.ui.internal.ui.CallActivity
77
import com.infobip.webrtc.ui.model.InCallButton
88
import com.infobip.webrtc.ui.view.styles.Colors
99
import com.infobip.webrtc.ui.view.styles.Icons
10-
import com.infobip.webrtc.ui.view.styles.IncomingCallMessageStyle
10+
import com.infobip.webrtc.ui.view.styles.InCallScreenStyle
11+
import com.infobip.webrtc.ui.view.styles.IncomingCallScreenStyle
1112
import com.infobip.webrtc.ui.view.styles.InfobipRtcUiTheme
1213
import java.util.Locale
1314

@@ -66,11 +67,9 @@ internal interface SdkLifetimeCache {
6667
var locale: Locale?
6768
var theme: InfobipRtcUiTheme?
6869
val colors: Colors?
69-
get() = theme?.colors
7070
val icons: Icons?
71-
get() = theme?.icons
72-
val incomingCallMessageStyle: IncomingCallMessageStyle?
73-
get() = theme?.incomingCallMessageStyle
71+
val incomingCallScreenStyle: IncomingCallScreenStyle?
72+
val inCallScreenStyle: InCallScreenStyle?
7473
var inCallButtons: List<InCallButton>
7574
var callErrorMapper: RtcUiCallErrorMapper?
7675
}
@@ -89,8 +88,11 @@ internal class SdkLifetimeCacheImpl : SdkLifetimeCache {
8988
get() = theme?.colors
9089
override val icons: Icons?
9190
get() = theme?.icons
92-
override val incomingCallMessageStyle: IncomingCallMessageStyle?
93-
get() = theme?.incomingCallMessageStyle
91+
override val incomingCallScreenStyle: IncomingCallScreenStyle?
92+
get() = theme?.incomingCallScreenStyle
93+
override val inCallScreenStyle: InCallScreenStyle?
94+
get() = theme?.inCallScreenStyle
95+
9496
override var inCallButtons: List<InCallButton> = emptyList()
9597
get() = field.takeIf { it.isNotEmpty() } ?: listOf(
9698
InCallButton.HangUp,

infobip-rtc-ui/src/main/java/com/infobip/webrtc/ui/internal/notification/CallNotificationFactory.kt

+19-7
Original file line numberDiff line numberDiff line change
@@ -117,11 +117,23 @@ internal class CallNotificationFactoryImpl(
117117
isSilent: Boolean,
118118
): Notification {
119119
val themedContext by lazy { ContextThemeWrapper(context, R.style.InfobipRtcUi_Call) }
120-
val incomeMessage: String? = Injector.cache.incomingCallMessageStyle?.messageText ?:
121-
themedContext.resolveStyledStringAttribute(R.styleable.InfobipRtcUi_rtc_ui_incoming_call_message, R.attr.infobipRtcUiStyle, R.styleable.InfobipRtcUi)
122-
val incomeHeadline: String? = Injector.cache.incomingCallMessageStyle?.headlineText ?:
123-
themedContext.resolveStyledStringAttribute(R.styleable.InfobipRtcUi_rtc_ui_incoming_call_headline, R.attr.infobipRtcUiStyle, R.styleable.InfobipRtcUi)
124-
val acceptCall = incomeMessage.isNullOrEmpty() && incomeHeadline.isNullOrEmpty()
120+
val incomingCallScreenMessage: String? = Injector.cache.incomingCallScreenStyle?.messageText ?: themedContext.resolveStyledStringAttribute(
121+
R.styleable.InfobipRtcUi_rtc_ui_incoming_call_message,
122+
R.attr.infobipRtcUiStyle,
123+
R.styleable.InfobipRtcUi
124+
)
125+
val incomingCallScreenHeadline: String? = Injector.cache.incomingCallScreenStyle?.headlineText ?: themedContext.resolveStyledStringAttribute(
126+
R.styleable.InfobipRtcUi_rtc_ui_incoming_call_headline,
127+
R.attr.infobipRtcUiStyle,
128+
R.styleable.InfobipRtcUi
129+
)
130+
val incomingCallScreenCallerName: String? = Injector.cache.incomingCallScreenStyle?.callerName ?: themedContext.resolveStyledStringAttribute(
131+
R.styleable.InfobipRtcUi_rtc_ui_incoming_call_caller_name,
132+
R.attr.infobipRtcUiStyle,
133+
R.styleable.InfobipRtcUi
134+
)
135+
val acceptCall = incomingCallScreenMessage.isNullOrEmpty() && incomingCallScreenHeadline.isNullOrEmpty()
136+
val displayName = incomingCallScreenCallerName ?: callerName
125137

126138
val acceptIntent = PendingIntent.getActivity(
127139
context, CALL_ACCEPT_REQUEST_CODE,
@@ -137,11 +149,11 @@ internal class CallNotificationFactoryImpl(
137149
updateCurrentImmutableFlags
138150
)
139151

140-
return commonCallNotification(callerName, description, INCOMING_CALL_NOTIFICATION_CHANNEL_ID) {
152+
return commonCallNotification(displayName, description, INCOMING_CALL_NOTIFICATION_CHANNEL_ID) {
141153
foregroundServiceBehavior = FOREGROUND_SERVICE_IMMEDIATE
142154
setStyle(
143155
NotificationCompat.CallStyle.forIncomingCall(
144-
Person.Builder().setName(callerName).setImportant(true).build(),
156+
Person.Builder().setName(displayName).setImportant(true).build(),
145157
declineIntent,
146158
acceptIntent
147159
)

infobip-rtc-ui/src/main/java/com/infobip/webrtc/ui/internal/ui/CallActivity.kt

+4-2
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,8 @@ import com.infobip.webrtc.ui.internal.utils.throttleFirst
5757
import com.infobip.webrtc.ui.model.RtcUiError
5858
import com.infobip.webrtc.ui.view.styles.Colors
5959
import com.infobip.webrtc.ui.view.styles.Icons
60-
import com.infobip.webrtc.ui.view.styles.IncomingCallMessageStyle
60+
import com.infobip.webrtc.ui.view.styles.InCallScreenStyle
61+
import com.infobip.webrtc.ui.view.styles.IncomingCallScreenStyle
6162
import com.infobip.webrtc.ui.view.styles.InfobipRtcUiTheme
6263
import kotlinx.coroutines.Dispatchers
6364
import kotlinx.coroutines.channels.Channel
@@ -116,9 +117,10 @@ class CallActivity : AppCompatActivity(R.layout.activity_call) {
116117
attrs: AttributeSet
117118
): View? {
118119
Injector.cache.theme = InfobipRtcUiTheme(
120+
incomingCallScreenStyle = Injector.cache.incomingCallScreenStyle ?: IncomingCallScreenStyle(this, attrs),
121+
inCallScreenStyle = Injector.cache.inCallScreenStyle ?: InCallScreenStyle(this, attrs),
119122
colors = Injector.cache.colors ?: Colors(this, attrs),
120123
icons = Injector.cache.icons ?: Icons(this, attrs),
121-
incomingCallMessageStyle = Injector.cache.incomingCallMessageStyle ?: IncomingCallMessageStyle(this, attrs)
122124
)
123125
return super.onCreateView(parent, name, context, attrs)
124126
}

infobip-rtc-ui/src/main/java/com/infobip/webrtc/ui/internal/ui/CallViewModel.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ internal class CallViewModel : ViewModel() {
160160
}
161161
}
162162

163-
fun toggleMute() {
163+
fun toggleMic() {
164164
runCatching {
165165
val newValue = !state.value.isMuted
166166
callsDelegate.mute(newValue)

infobip-rtc-ui/src/main/java/com/infobip/webrtc/ui/internal/ui/fragment/InCallFragment.kt

+32-24
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ import com.infobip.webrtc.ui.internal.core.TAG
4646
import com.infobip.webrtc.ui.internal.model.CallState
4747
import com.infobip.webrtc.ui.internal.service.ScreenShareService
4848
import com.infobip.webrtc.ui.internal.ui.CallViewModel
49+
import com.infobip.webrtc.ui.internal.ui.view.CallAlert
4950
import com.infobip.webrtc.ui.internal.ui.view.CircleImageButton
5051
import com.infobip.webrtc.ui.internal.ui.view.InCallButtonAbs
5152
import com.infobip.webrtc.ui.internal.ui.view.PipParamsFactory
@@ -75,8 +76,12 @@ class InCallFragment : Fragment() {
7576
const val PIP_ACTION_VIDEO = 3
7677
const val PIP_ACTION_HANGUP = 4
7778

78-
fun pipActionIntent(pipAction: Int): Intent {
79+
fun pipActionIntent(
80+
context: Context,
81+
pipAction: Int
82+
): Intent {
7983
return Intent(ACTION_PIP).apply {
84+
setPackage(context.packageName)
8085
putExtra(EXTRAS_PIP_ACTION, pipAction)
8186
}
8287
}
@@ -145,7 +150,7 @@ class InCallFragment : Fragment() {
145150
override fun onReceive(context: Context?, intent: Intent?) {
146151
if (intent?.action == ACTION_PIP) {
147152
when (intent.getIntExtra(EXTRAS_PIP_ACTION, 0)) {
148-
PIP_ACTION_MUTE -> toggleMute()
153+
PIP_ACTION_MUTE -> toggleMic()
149154
PIP_ACTION_SPEAKER -> toggleSpeaker()
150155
PIP_ACTION_VIDEO -> toggleVideo()
151156
PIP_ACTION_HANGUP -> viewModel.hangup()
@@ -156,7 +161,7 @@ class InCallFragment : Fragment() {
156161
}
157162

158163
private var speakerButton: InCallButtonAbs? = null
159-
private var muteButton: InCallButtonAbs? = null
164+
private var micButton: InCallButtonAbs? = null
160165
private var flipCamButton: InCallButtonAbs? = null
161166
private var screenShareButton: InCallButtonAbs? = null
162167
private var videoButton: InCallButtonAbs? = null
@@ -243,7 +248,7 @@ class InCallFragment : Fragment() {
243248
setScalingType(RendererCommon.ScalingType.SCALE_ASPECT_FILL)
244249
}
245250
screenSharingRenderers.setOnTouchListener(getLocalVideoTouchListener())
246-
viewModel.peerName.let {
251+
(Injector.cache.inCallScreenStyle?.callerName ?: viewModel.peerName).let {
247252
nameInVoice.text = it
248253
nameInVideo.text = it
249254
nameInPip.text = it
@@ -348,10 +353,10 @@ class InCallFragment : Fragment() {
348353
}
349354
}
350355

351-
R.id.rtc_ui_mute_button -> {
352-
muteButton = button
353-
muteButton?.setOnClickListener {
354-
toggleMute()
356+
R.id.rtc_ui_mic_button -> {
357+
micButton = button
358+
micButton?.setOnClickListener {
359+
toggleMic()
355360
buttonDesc.onClick()
356361
}
357362
}
@@ -392,10 +397,9 @@ class InCallFragment : Fragment() {
392397
R.id.rtc_ui_hang_up_button -> {
393398
hangupButton = button
394399
Injector.cache.colors?.let { res ->
395-
hangupButton?.setIconTint(ColorStateList.valueOf(res.rtcUiActionsIcon))
396-
hangupButton?.setBackgroundColor(ColorStateList.valueOf(res.rtcUiHangup))
400+
hangupButton?.setIconTint(ColorStateList.valueOf(res.actionsIcon))
401+
hangupButton?.setBackgroundColor(ColorStateList.valueOf(res.hangup))
397402
}
398-
hangupButton?.setLabelColor()
399403
hangupButton?.setOnClickListener {
400404
viewModel.hangup()
401405
}
@@ -438,10 +442,11 @@ class InCallFragment : Fragment() {
438442
//screenshare
439443
binding.screenSharingNotice.isVisible = isLocalScreenShare
440444
binding.screenSharingDisable.isVisible = isLocalScreenShare && !isPip
441-
Injector.cache.colors.let { res -> (if (isLocalScreenShare) res?.rtcUiActionsBackground else res?.rtcUiBackground)?.let { binding.background.setBackgroundColor(it) } }
445+
Injector.cache.colors.let { res -> (if (isLocalScreenShare) res?.actionsBackground else res?.background)?.let { binding.background.setBackgroundColor(it) } }
442446
//another views
443447
binding.connectionAlert.isVisible = callAlert != null && !isPip && showControls
444448
binding.connectionAlert.setMode(callAlert)
449+
binding.mutedMicrophoneAlert.setMode(CallAlert.Mode.DisabledMic)
445450
binding.mutedMicrophoneAlert.isVisible = isMuted && !isPip && showControls
446451
binding.peerMuteIndicatorInVideo.isVisible = (isRemoteVideo || isLocalScreenShare || isRemoteScreenShare) && isPeerMuted == true && !isPip && showControls
447452
binding.peerMuteIndicatorInVoice.isVisible = !isRemoteVideo && !isLocalScreenShare && !isRemoteScreenShare && isPeerMuted == true && !isPip
@@ -452,11 +457,14 @@ class InCallFragment : Fragment() {
452457
binding.bottomSheet.bottomSheetButtons.isVisible = !isPip
453458
showFlipCam(isLocalVideo)
454459
//check state
455-
muteButton?.isChecked = !isMuted
460+
micButton?.isChecked = isMuted
456461
speakerButton?.isChecked = isSpeakerOn
457462
screenShareButton?.isChecked = isLocalScreenShare
458463
videoButton?.isChecked = isLocalVideo
459-
customInCallButtons.forEach { it.refreshChecked(); it.refreshEnabled() }
464+
customInCallButtons.forEach {
465+
it.refreshChecked()
466+
it.refreshEnabled()
467+
}
460468
}
461469
}
462470

@@ -541,8 +549,8 @@ class InCallFragment : Fragment() {
541549
viewModel.toggleVideo()
542550
}
543551

544-
private fun toggleMute() {
545-
viewModel.toggleMute()
552+
private fun toggleMic() {
553+
viewModel.toggleMic()
546554
}
547555

548556
private fun toggleSpeaker() {
@@ -579,23 +587,23 @@ class InCallFragment : Fragment() {
579587

580588
private fun customize() {
581589
Injector.cache.colors?.let { res ->
582-
val foregroundColorStateList = ColorStateList.valueOf(res.rtcUiForeground)
590+
val foregroundColorStateList = ColorStateList.valueOf(res.foreground)
583591
with(binding) {
584-
toolbarBackground.setBackgroundColor(res.rtcUiOverlayBackground)
592+
toolbarBackground.setBackgroundColor(res.overlayBackground)
585593
nameInVideo.setTextColor(foregroundColorStateList)
586594
nameInVoice.setTextColor(foregroundColorStateList)
587595
nameInPip.setTextColor(foregroundColorStateList)
588596
peerMuteIndicatorInVideo.imageTintList = foregroundColorStateList
589597
peerMuteIndicatorInVoice.imageTintList = foregroundColorStateList
590-
nameDivider.setBackgroundColor(res.rtcUiForeground)
598+
nameDivider.setBackgroundColor(res.foreground)
591599
elapsedTimeVideo.setTextColor(foregroundColorStateList)
592600
elapsedTimeVoice.setTextColor(foregroundColorStateList)
593601
collapseCallButton.imageTintList = foregroundColorStateList
594602
avatar.imageTintList = foregroundColorStateList
595-
background.setBackgroundColor(res.rtcUiBackground)
596-
bottomSheet.pill.backgroundTintList = ColorStateList.valueOf(res.rtcUiColorSheetPill)
597-
bottomSheet.divider.setBackgroundColor(res.rtcUiColorActionsDivider)
598-
bottomSheet.bottomSheetButtons.setBackgroundColor(res.rtcUiColorSheetBackground)
603+
background.setBackgroundColor(res.background)
604+
bottomSheet.pill.backgroundTintList = ColorStateList.valueOf(res.sheetPill)
605+
bottomSheet.divider.setBackgroundColor(res.actionsDivider)
606+
bottomSheet.bottomSheetButtons.setBackgroundColor(res.sheetBackground)
599607
}
600608
}
601609
}
@@ -700,7 +708,7 @@ class InCallFragment : Fragment() {
700708
}
701709
_binding = null
702710
hangupButton?.setOnClickListener(null)
703-
muteButton?.setOnClickListener(null)
711+
micButton?.setOnClickListener(null)
704712
speakerButton?.setOnClickListener(null)
705713
flipCamButton?.setOnClickListener(null)
706714
videoButton?.setOnClickListener(null)

0 commit comments

Comments
 (0)