Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
eecc9e2
bugfix: Handle incoming call from OnNewIntent in StreamCallActivity
rahul-lohra Jul 18, 2025
b857124
bugfix: Handle incoming call from OnNewIntent in StreamCallActivity
rahul-lohra Jul 18, 2025
7dcce54
bugfix: Handle incoming call from OnNewIntent in StreamCallActivity
rahul-lohra Jul 18, 2025
933de4f
bugfix: Handle incoming call from OnNewIntent in StreamCallActivity
rahul-lohra Jul 18, 2025
97a149a
bugfix: Handle Group call rejection on Android
rahul-lohra Jul 22, 2025
6cf66bc
api dump
rahul-lohra Jul 22, 2025
1ba7bd6
api dump
rahul-lohra Jul 22, 2025
b5b2475
minor update
rahul-lohra Jul 22, 2025
b7c175a
Call reject in bigger lifecycle scope
rahul-lohra Jul 22, 2025
d30e4b4
fix: Avoid double finish by adding a safe finish
rahul-lohra Jul 23, 2025
b3e1dbe
fix: Deprecate methods which didn't had call object
rahul-lohra Jul 24, 2025
6b349df
temp: Introduce a way to handle multiple calls in the activity.
rahul-lohra Jul 25, 2025
58b7a1e
temp: Remove deprecation checkpoint 1
rahul-lohra Jul 25, 2025
0232913
temp: api dump
rahul-lohra Jul 25, 2025
ed58009
temp: Add StreamCallActivityException
rahul-lohra Jul 25, 2025
d51cc6d
temp: spotless
rahul-lohra Jul 25, 2025
5eca8be
temp: spotless
rahul-lohra Jul 25, 2025
cce15d9
chore: Update kdoc
rahul-lohra Jul 25, 2025
e2d1fa5
chore: Update kdoc
rahul-lohra Jul 25, 2025
a7ac5f6
chore: Update kdoc
rahul-lohra Jul 25, 2025
38304e1
chore: Update kdoc
rahul-lohra Jul 25, 2025
0107857
chore: Update kdoc
rahul-lohra Jul 25, 2025
838e2d7
chore: Update kdoc
rahul-lohra Jul 25, 2025
21e059b
Merge branch 'develop' into feature/rahullohra/group-calls
aleksandar-apostolov Jul 28, 2025
4e46c1a
Merge branch 'develop' into feature/rahullohra/group-calls
aleksandar-apostolov Jul 28, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,11 @@ import kotlinx.coroutines.runBlocking
class CallActivity : ComposeStreamCallActivity() {

override val uiDelegate: StreamActivityUiDelegate<StreamCallActivity> = StreamDemoUiDelegate()
override val configuration: StreamCallActivityConfiguration =
StreamCallActivityConfiguration(
closeScreenOnCallEnded = false,
canSkipPermissionRationale = false,
)

override fun loadConfigFromIntent(intent: Intent?): StreamCallActivityConfiguration {
return super.loadConfigFromIntent(intent)
.copy(closeScreenOnCallEnded = false, canSkipPermissionRationale = false)
}

override fun onNewIntent(intent: Intent) {
super.onNewIntent(intent)
Expand Down Expand Up @@ -144,7 +144,7 @@ class CallActivity : ComposeStreamCallActivity() {
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
}
startActivity(intent)
finish()
safeFinish()
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,12 @@ import io.getstream.video.android.tooling.util.StreamBuildFlavorUtil
import io.getstream.video.android.ui.AppNavHost
import io.getstream.video.android.ui.AppScreens
import io.getstream.video.android.ui.common.StreamCallActivity
import io.getstream.video.android.ui.common.StreamCallActivityConfiguration
import io.getstream.video.android.util.InAppUpdateHelper
import io.getstream.video.android.util.InstallReferrer
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.emptyFlow
import kotlinx.coroutines.flow.firstOrNull
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.flowOf
Expand Down Expand Up @@ -104,30 +106,42 @@ class MainActivity : ComponentActivity() {
observeIncomingCall()
}

/**
* Observes incoming calls in real-time.
*
* - First, it waits for the StreamVideo instance to be available.
* - Then it watches for a "ringing" call (i.e., someone is calling).
* - Once a ringing call is found, it listens for its ringing state updates.
* - If the ringing state changes to "Incoming", it means we are receiving a call.
* - At that point, it starts the incoming call screen using `startIncomingCallActivity()`.
*
* This flow automatically stops and restarts if the instance or call changes,
* ensuring we always react to the latest incoming call state.
*/
@OptIn(ExperimentalCoroutinesApi::class)
private fun observeIncomingCall() {
lifecycleScope.launch {
StreamVideo.instanceState.flatMapLatest { instance ->
instance?.state?.ringingCall ?: flowOf(null)
}.collectLatest { call ->
if (call != null) {
lifecycleScope.launch {
// Monitor the ringingState on a non-null call
call.state.ringingState.collectLatest {
if (it is RingingState.Incoming) {
startIncomingCallActivity(call)
}
}
StreamVideo.instanceState
.flatMapLatest { instance ->
instance?.state?.ringingCall ?: flowOf(null)
}
.flatMapLatest { call ->
call?.state?.ringingState ?: emptyFlow()
}
.collectLatest { ringingState ->
val currentCall = StreamVideo.instanceState.value?.state?.ringingCall?.value
if (ringingState is RingingState.Incoming) {
currentCall?.let { startIncomingCallActivity(it) }
}
}
}
}
}

fun startIncomingCallActivity(call: Call) {
val intent = StreamCallActivity.callIntent(
context = this,
cid = StreamCallId.fromCallCid(call.cid),
configuration = StreamCallActivityConfiguration(closeScreenOnCallEnded = true),
members = emptyList(),
leaveWhenLastInCall = true,
action = NotificationHandler.ACTION_INCOMING_CALL,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5647,6 +5647,7 @@ public final class io/getstream/video/android/core/CallState {
public final fun updateParticipantSortingOrder (Ljava/util/Comparator;)V
public final fun updateParticipantVisibility (Ljava/lang/String;Lio/getstream/video/android/core/model/VisibilityOnScreenState;)V
public final fun updateParticipantVisibilityFlow (Lkotlinx/coroutines/flow/Flow;)V
public final fun updateRejectedBy (Ljava/util/Set;)V
public final fun upsertParticipants (Ljava/util/List;)V
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1525,6 +1525,10 @@ public class CallState(
null
}
}

fun updateRejectedBy(userId: Set<String>) {
_rejectedBy.value = userId
}
}

private fun MemberResponse.toMemberState(): MemberState {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ public open class StreamCallActivityComposeDelegate : StreamCallActivityComposeU
centerContent = { },
onCallAction = {
call.leave()
finish()
safeFinish()
},
)
}
Expand Down Expand Up @@ -332,7 +332,7 @@ public open class StreamCallActivityComposeDelegate : StreamCallActivityComposeU
) {
if (!showRationale && configuration.canSkipPermissionRationale) {
logger.w { "Permissions were not granted, but rationale is required to be skipped." }
finish()
safeFinish()
} else {
PermissionsRationaleContent(call, granted, notGranted)
}
Expand All @@ -355,7 +355,7 @@ public open class StreamCallActivityComposeDelegate : StreamCallActivityComposeU
CallDisconnectedContent(call)
} else {
// This is just for safety, will be called from other place as well.
finish()
safeFinish()
}
}

Expand All @@ -365,7 +365,7 @@ public open class StreamCallActivityComposeDelegate : StreamCallActivityComposeU
CallFailedContent(call, err)
} else {
// This is just for safety, will be called from other place as well.
finish()
safeFinish()
}
}

Expand Down Expand Up @@ -472,14 +472,14 @@ public open class StreamCallActivityComposeDelegate : StreamCallActivityComposeU
override fun StreamCallActivity.CallFailedContent(call: Call, exception: java.lang.Exception) {
// By default we finish the activity regardless of config.
// There is not default UI for call failed content.
finish()
safeFinish()
}

@Composable
override fun StreamCallActivity.CallDisconnectedContent(call: Call) {
// By default we finish the activity regardless of config.
// There is not default UI for call ended content.
finish()
safeFinish()
}

@Composable
Expand Down
Loading