Skip to content

Commit 6a048fd

Browse files
committed
improve/fix contents for picture in picture mode
depending on amount of participants, voiceOnly call and enabled/disabled own video, the contents of PIP windows are updated. This will be further improved when speaker-view is implemented. Signed-off-by: Marcel Hibbe <[email protected]>
1 parent eaed930 commit 6a048fd

File tree

4 files changed

+69
-57
lines changed

4 files changed

+69
-57
lines changed

app/src/main/java/com/nextcloud/talk/activities/CallActivity.kt

Lines changed: 27 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -938,35 +938,17 @@ class CallActivity : CallBaseActivity() {
938938
binding!!.pipSelfVideoRenderer.release()
939939
}
940940

941-
private fun initSelfVideoViewForPipMode() {
942-
if (!isVoiceOnlyCall) {
943-
binding!!.pipSelfVideoRenderer.visibility = View.VISIBLE
944-
try {
945-
binding!!.pipSelfVideoRenderer.init(rootEglBase!!.eglBaseContext, null)
946-
} catch (e: IllegalStateException) {
947-
Log.d(TAG, "pipGroupVideoRenderer already initialized", e)
948-
}
949-
binding!!.pipSelfVideoRenderer.setZOrderMediaOverlay(true)
950-
// disabled because it causes some devices to crash
951-
binding!!.pipSelfVideoRenderer.setEnableHardwareScaler(false)
952-
binding!!.pipSelfVideoRenderer.setScalingType(RendererCommon.ScalingType.SCALE_ASPECT_FIT)
953-
954-
localVideoTrack?.addSink(binding?.pipSelfVideoRenderer)
955-
} else {
956-
binding!!.pipSelfVideoRenderer.visibility = View.GONE
957-
}
958-
}
959-
960941
private fun initGrid() {
961942
Log.d(TAG, "initGrid")
962-
943+
binding!!.composeParticipantGrid.visibility = View.VISIBLE
963944
binding!!.composeParticipantGrid.setContent {
964945
MaterialTheme {
965946
val participantUiStates = participantItems.map { it.uiStateFlow.collectAsState().value }
966947
ParticipantGrid(
967948
participantUiStates = participantUiStates,
968949
eglBase = rootEglBase!!,
969-
isVoiceOnlyCall = isVoiceOnlyCall
950+
isVoiceOnlyCall = isVoiceOnlyCall,
951+
isInPipMode = isInPipMode
970952
) {
971953
animateCallControls(true, 0)
972954
}
@@ -3206,40 +3188,46 @@ class CallActivity : CallBaseActivity() {
32063188

32073189
override fun updateUiForPipMode() {
32083190
Log.d(TAG, "updateUiForPipMode")
3209-
val params = RelativeLayout.LayoutParams(
3210-
ViewGroup.LayoutParams.MATCH_PARENT,
3211-
ViewGroup.LayoutParams.WRAP_CONTENT
3212-
)
3213-
params.setMargins(0, 0, 0, 0)
3214-
binding!!.composeParticipantGrid.layoutParams = params
32153191
binding!!.callControls.visibility = View.GONE
32163192
binding!!.callInfosLinearLayout.visibility = View.GONE
32173193
binding!!.selfVideoViewWrapper.visibility = View.GONE
32183194
binding!!.callStates.callStateRelativeLayout.visibility = View.GONE
32193195
binding!!.pipCallConversationNameTextView.text = conversationName
32203196

3221-
if (isVoiceOnlyCall) {
3222-
if (participantItems.size > 1) {
3223-
binding!!.pipOverlay.visibility = View.VISIBLE
3224-
binding!!.pipSelfVideoRenderer.visibility = View.GONE
3225-
} else {
3226-
binding!!.pipOverlay.visibility = View.GONE
3227-
}
3197+
binding!!.selfVideoRenderer.clearImage()
3198+
binding!!.selfVideoRenderer.release()
3199+
3200+
if (participantItems.size == 1) {
3201+
binding!!.pipOverlay.visibility = View.GONE
32283202
} else {
3229-
binding!!.selfVideoRenderer.clearImage()
3230-
binding!!.selfVideoRenderer.release()
3231-
if (participantItems.size > 1) {
3203+
binding!!.composeParticipantGrid.visibility = View.GONE
3204+
3205+
if (localVideoTrack?.enabled() == true) {
32323206
binding!!.pipOverlay.visibility = View.VISIBLE
3233-
initSelfVideoViewForPipMode()
3207+
binding!!.pipSelfVideoRenderer.visibility = View.VISIBLE
3208+
3209+
try {
3210+
binding!!.pipSelfVideoRenderer.init(rootEglBase!!.eglBaseContext, null)
3211+
} catch (e: IllegalStateException) {
3212+
Log.d(TAG, "pipGroupVideoRenderer already initialized", e)
3213+
}
3214+
binding!!.pipSelfVideoRenderer.setZOrderMediaOverlay(true)
3215+
// disabled because it causes some devices to crash
3216+
binding!!.pipSelfVideoRenderer.setEnableHardwareScaler(false)
3217+
binding!!.pipSelfVideoRenderer.setScalingType(RendererCommon.ScalingType.SCALE_ASPECT_FIT)
3218+
3219+
localVideoTrack?.addSink(binding?.pipSelfVideoRenderer)
32343220
} else {
3235-
binding!!.pipOverlay.visibility = View.GONE
3221+
binding!!.pipOverlay.visibility = View.VISIBLE
3222+
binding!!.pipSelfVideoRenderer.visibility = View.GONE
32363223
}
32373224
}
32383225
}
32393226

32403227
override fun updateUiForNormalMode() {
32413228
Log.d(TAG, "updateUiForNormalMode")
32423229
binding!!.pipOverlay.visibility = View.GONE
3230+
binding!!.composeParticipantGrid.visibility = View.VISIBLE
32433231

32443232
if (isVoiceOnlyCall) {
32453233
binding!!.callControls.visibility = View.VISIBLE

app/src/main/java/com/nextcloud/talk/call/components/AvatarWithFallback.kt

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ package com.nextcloud.talk.call.components
1010
import androidx.compose.foundation.background
1111
import androidx.compose.foundation.layout.Box
1212
import androidx.compose.foundation.layout.fillMaxSize
13-
import androidx.compose.foundation.layout.size
1413
import androidx.compose.foundation.shape.CircleShape
1514
import androidx.compose.material3.Text
1615
import androidx.compose.runtime.Composable
@@ -19,7 +18,6 @@ import androidx.compose.ui.Modifier
1918
import androidx.compose.ui.draw.clip
2019
import androidx.compose.ui.graphics.Color
2120
import androidx.compose.ui.layout.ContentScale
22-
import androidx.compose.ui.unit.dp
2321
import androidx.compose.ui.unit.sp
2422
import coil.compose.AsyncImage
2523
import com.nextcloud.talk.adapters.ParticipantUiState
@@ -34,7 +32,6 @@ fun AvatarWithFallback(participant: ParticipantUiState, modifier: Modifier = Mod
3432

3533
Box(
3634
modifier = modifier
37-
.size(150.dp)
3835
.clip(CircleShape),
3936
contentAlignment = Alignment.Center
4037
) {

app/src/main/java/com/nextcloud/talk/call/components/ParticipantGrid.kt

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,14 @@ import com.nextcloud.talk.adapters.ParticipantUiState
2929
import org.webrtc.EglBase
3030
import kotlin.math.ceil
3131

32+
@Suppress("LongParameterList")
3233
@Composable
3334
fun ParticipantGrid(
3435
modifier: Modifier = Modifier,
3536
eglBase: EglBase?,
3637
participantUiStates: List<ParticipantUiState>,
3738
isVoiceOnlyCall: Boolean,
39+
isInPipMode: Boolean,
3840
onClick: () -> Unit
3941
) {
4042
val configuration = LocalConfiguration.current
@@ -58,7 +60,7 @@ fun ParticipantGrid(
5860

5961
val rows = ceil(participantUiStates.size / columns.toFloat()).toInt()
6062

61-
val heightForNonGridComponents = if (isVoiceOnlyCall) {
63+
val heightForNonGridComponents = if (isVoiceOnlyCall && !isInPipMode) {
6264
// this is a workaround for now. It should ~summarize the height of callInfosLinearLayout and callControls
6365
// Once everything is migrated to jetpack, this workaround should be obsolete or solved in a better way
6466
240.dp
@@ -97,6 +99,7 @@ fun ParticipantGrid(
9799
.height(itemHeight)
98100
.fillMaxWidth(),
99101
eglBase = eglBase,
102+
isInPipMode = isInPipMode,
100103
isVoiceOnlyCall = isVoiceOnlyCall
101104
)
102105
}
@@ -109,7 +112,8 @@ fun ParticipantGridPreview() {
109112
ParticipantGrid(
110113
participantUiStates = getTestParticipants(1),
111114
eglBase = null,
112-
isVoiceOnlyCall = false
115+
isVoiceOnlyCall = false,
116+
isInPipMode = false
113117
) {}
114118
}
115119

@@ -119,7 +123,8 @@ fun TwoParticipants() {
119123
ParticipantGrid(
120124
participantUiStates = getTestParticipants(2),
121125
eglBase = null,
122-
isVoiceOnlyCall = false
126+
isVoiceOnlyCall = false,
127+
isInPipMode = false
123128
) {}
124129
}
125130

@@ -129,7 +134,8 @@ fun ThreeParticipants() {
129134
ParticipantGrid(
130135
participantUiStates = getTestParticipants(3),
131136
eglBase = null,
132-
isVoiceOnlyCall = false
137+
isVoiceOnlyCall = false,
138+
isInPipMode = false
133139
) {}
134140
}
135141

@@ -139,7 +145,8 @@ fun FourParticipants() {
139145
ParticipantGrid(
140146
participantUiStates = getTestParticipants(4),
141147
eglBase = null,
142-
isVoiceOnlyCall = false
148+
isVoiceOnlyCall = false,
149+
isInPipMode = false
143150
) {}
144151
}
145152

@@ -149,7 +156,8 @@ fun FiveParticipants() {
149156
ParticipantGrid(
150157
participantUiStates = getTestParticipants(5),
151158
eglBase = null,
152-
isVoiceOnlyCall = false
159+
isVoiceOnlyCall = false,
160+
isInPipMode = false
153161
) {}
154162
}
155163

@@ -159,7 +167,8 @@ fun SevenParticipants() {
159167
ParticipantGrid(
160168
participantUiStates = getTestParticipants(7),
161169
eglBase = null,
162-
isVoiceOnlyCall = false
170+
isVoiceOnlyCall = false,
171+
isInPipMode = false
163172
) {}
164173
}
165174

@@ -169,7 +178,8 @@ fun FiftyParticipants() {
169178
ParticipantGrid(
170179
participantUiStates = getTestParticipants(50),
171180
eglBase = null,
172-
isVoiceOnlyCall = false
181+
isVoiceOnlyCall = false,
182+
isInPipMode = false
173183
) {}
174184
}
175185

@@ -183,7 +193,8 @@ fun OneParticipantLandscape() {
183193
ParticipantGrid(
184194
participantUiStates = getTestParticipants(1),
185195
eglBase = null,
186-
isVoiceOnlyCall = false
196+
isVoiceOnlyCall = false,
197+
isInPipMode = false
187198
) {}
188199
}
189200

@@ -197,7 +208,8 @@ fun TwoParticipantsLandscape() {
197208
ParticipantGrid(
198209
participantUiStates = getTestParticipants(2),
199210
eglBase = null,
200-
isVoiceOnlyCall = false
211+
isVoiceOnlyCall = false,
212+
isInPipMode = false
201213
) {}
202214
}
203215

@@ -211,7 +223,8 @@ fun ThreeParticipantsLandscape() {
211223
ParticipantGrid(
212224
participantUiStates = getTestParticipants(3),
213225
eglBase = null,
214-
isVoiceOnlyCall = false
226+
isVoiceOnlyCall = false,
227+
isInPipMode = false
215228
) {}
216229
}
217230

@@ -225,7 +238,8 @@ fun FourParticipantsLandscape() {
225238
ParticipantGrid(
226239
participantUiStates = getTestParticipants(4),
227240
eglBase = null,
228-
isVoiceOnlyCall = false
241+
isVoiceOnlyCall = false,
242+
isInPipMode = false
229243
) {}
230244
}
231245

@@ -239,7 +253,8 @@ fun SevenParticipantsLandscape() {
239253
ParticipantGrid(
240254
participantUiStates = getTestParticipants(7),
241255
eglBase = null,
242-
isVoiceOnlyCall = false
256+
isVoiceOnlyCall = false,
257+
isInPipMode = false
243258
) {}
244259
}
245260

@@ -253,7 +268,8 @@ fun FiftyParticipantsLandscape() {
253268
ParticipantGrid(
254269
participantUiStates = getTestParticipants(50),
255270
eglBase = null,
256-
isVoiceOnlyCall = false
271+
isVoiceOnlyCall = false,
272+
isInPipMode = false
257273
) {}
258274
}
259275

app/src/main/java/com/nextcloud/talk/call/components/ParticipantTile.kt

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,12 @@ import org.webrtc.EglBase
3636
const val NICK_OFFSET = 4f
3737
const val NICK_BLUR_RADIUS = 4f
3838

39+
@Suppress("Detekt.LongMethod")
3940
@Composable
4041
fun ParticipantTile(
4142
participantUiState: ParticipantUiState,
4243
eglBase: EglBase?,
44+
isInPipMode: Boolean,
4345
modifier: Modifier = Modifier,
4446
isVoiceOnlyCall: Boolean
4547
) {
@@ -53,9 +55,17 @@ fun ParticipantTile(
5355
if (!isVoiceOnlyCall && participantUiState.isStreamEnabled && participantUiState.mediaStream != null) {
5456
WebRTCVideoView(participantUiState, eglBase)
5557
} else {
58+
val avatarSize = if (isInPipMode) {
59+
100.dp
60+
} else {
61+
150.dp
62+
}
63+
5664
AvatarWithFallback(
5765
participant = participantUiState,
58-
modifier = Modifier.align(Alignment.Center)
66+
modifier = Modifier
67+
.align(Alignment.Center)
68+
.size(avatarSize)
5969
)
6070
}
6171

@@ -125,6 +135,7 @@ fun ParticipantTilePreview() {
125135
.fillMaxWidth()
126136
.height(300.dp),
127137
eglBase = null,
138+
isInPipMode = false,
128139
isVoiceOnlyCall = false
129140
)
130141
}

0 commit comments

Comments
 (0)