Added support of PiP

This commit is contained in:
Sylvain Berfini 2023-09-11 14:49:39 +02:00
parent e4551713dc
commit f6479826ca
5 changed files with 95 additions and 6 deletions

View file

@ -19,6 +19,8 @@
*/
package org.linphone.ui.voip
import android.app.PictureInPictureParams
import android.content.pm.PackageManager
import android.os.Bundle
import android.view.ViewGroup
import androidx.annotation.DrawableRes
@ -103,6 +105,7 @@ class VoipActivity : AppCompatActivity() {
callViewModel = run {
ViewModelProvider(this)[CurrentCallViewModel::class.java]
}
binding.callViewModel = callViewModel
callViewModel.showAudioDevicesListEvent.observe(this) {
it.consume { devices ->
@ -172,6 +175,43 @@ class VoipActivity : AppCompatActivity() {
}
}
override fun onResume() {
super.onResume()
val isInPipMode = isInPictureInPictureMode
if (::callViewModel.isInitialized) {
Log.i("$TAG onResume: is in PiP mode? $isInPipMode")
callViewModel.pipMode.value = isInPipMode
}
}
override fun onUserLeaveHint() {
super.onUserLeaveHint()
if (::callViewModel.isInitialized && callViewModel.isVideoEnabled.value == true) {
Log.i("$TAG User leave hint, entering PiP mode")
val supportsPip = packageManager.hasSystemFeature(
PackageManager.FEATURE_PICTURE_IN_PICTURE
)
Log.i("$TAG Is PiP supported: $supportsPip")
if (supportsPip) {
val params = PictureInPictureParams.Builder()
.setAspectRatio(AppUtils.getPipRatio(this))
.build()
try {
if (!enterPictureInPictureMode(params)) {
Log.e("$TAG Failed to enter PiP mode")
callViewModel.pipMode.value = false
} else {
Log.i("$TAG Entered PiP mode")
}
} catch (e: Exception) {
Log.e("$TAG Can't build PiP params: $e")
}
}
}
}
private fun updateCurrentLayout(newLayoutInfo: WindowLayoutInfo) {
if (newLayoutInfo.displayFeatures.isNotEmpty()) {
for (feature in newLayoutInfo.displayFeatures) {

View file

@ -67,6 +67,8 @@ class CurrentCallViewModel @UiThread constructor() : ViewModel() {
val fullScreenMode = MutableLiveData<Boolean>()
val pipMode = MutableLiveData<Boolean>()
// To synchronize chronometers in UI
val callDuration = MutableLiveData<Int>()

View file

@ -19,7 +19,10 @@
*/
package org.linphone.utils
import android.app.Activity
import android.content.Context
import android.util.DisplayMetrics
import android.util.Rational
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
@ -50,6 +53,42 @@ class AppUtils {
return coreContext.context.getString(id, args)
}
@MainThread
fun getPipRatio(
activity: Activity,
forcePortrait: Boolean = false,
forceLandscape: Boolean = false
): Rational {
val displayMetrics = DisplayMetrics()
activity.windowManager.defaultDisplay.getMetrics(displayMetrics)
var height = displayMetrics.heightPixels
var width = displayMetrics.widthPixels
val aspectRatio = width / height
if (aspectRatio < 1 / 2.39) {
height = 2.39.toInt()
width = 1
} else if (aspectRatio > 2.39) {
width = 2.39.toInt()
height = 1
}
val ratio = if (width > height) {
if (forcePortrait) {
Rational(height, width)
} else {
Rational(width, height)
}
} else {
if (forceLandscape) {
Rational(height, width)
} else {
Rational(width, height)
}
}
return ratio
}
@MainThread
fun getRedToast(
context: Context,

View file

@ -113,13 +113,19 @@
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"/>
<androidx.constraintlayout.widget.Group
android:id="@+id/header_info_visibility"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="@{viewModel.fullScreenMode || viewModel.pipMode ? View.INVISIBLE : View.VISIBLE}"
app:constraint_referenced_ids="call_direction_icon, call_direction_label, separator, chronometer" />
<ImageView
android:id="@+id/call_direction_icon"
android:layout_width="@dimen/icon_size"
android:layout_height="@dimen/icon_size"
android:layout_marginStart="10dp"
android:adjustViewBounds="true"
android:visibility="@{viewModel.fullScreenMode ? View.GONE : View.VISIBLE}"
android:src="@{viewModel.isOutgoing ? @drawable/outgoing_call : @drawable/incoming_call, default=@drawable/outgoing_call}"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@id/call_direction_label"
@ -133,7 +139,6 @@
android:layout_marginStart="10dp"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
android:visibility="@{viewModel.fullScreenMode ? View.GONE : View.VISIBLE}"
android:text="@{viewModel.isOutgoing ? @string/call_outgoing : @string/call_incoming, default=@string/call_outgoing}"
android:textColor="@color/white"
android:textSize="16sp"
@ -150,7 +155,6 @@
android:textColor="@color/white"
android:textSize="16sp"
android:text="@string/vertical_separator"
android:visibility="@{viewModel.fullScreenMode ? View.GONE : View.VISIBLE}"
app:layout_constraintStart_toEndOf="@id/call_direction_label"
app:layout_constraintTop_toTopOf="@id/call_direction_label"
app:layout_constraintBottom_toBottomOf="@id/call_direction_label"/>
@ -163,7 +167,6 @@
android:layout_marginStart="5dp"
android:textColor="@color/white"
android:textSize="16sp"
android:visibility="@{viewModel.fullScreenMode ? View.GONE : View.VISIBLE}"
app:layout_constraintStart_toEndOf="@id/separator"
app:layout_constraintTop_toTopOf="@id/call_direction_label"
app:layout_constraintBottom_toBottomOf="@id/call_direction_label"/>
@ -176,7 +179,7 @@
android:padding="5dp"
android:layout_marginEnd="10dp"
android:src="@drawable/camera_rotate"
android:visibility="@{!viewModel.fullScreenMode &amp;&amp; viewModel.isVideoEnabled &amp;&amp; viewModel.showSwitchCamera ? View.VISIBLE : View.GONE}"
android:visibility="@{!viewModel.fullScreenMode &amp;&amp; !viewModel.pipMode &amp;&amp; viewModel.isVideoEnabled &amp;&amp; viewModel.showSwitchCamera ? View.VISIBLE : View.GONE}"
app:tint="@color/white"
app:layout_constraintTop_toTopOf="@id/call_direction_label"
app:layout_constraintBottom_toBottomOf="@id/call_direction_label"
@ -200,7 +203,7 @@
<include
android:id="@+id/bottom_bar"
android:visibility="@{viewModel.fullScreenMode ? View.GONE : View.VISIBLE}"
android:visibility="@{viewModel.fullScreenMode || viewModel.pipMode ? View.INVISIBLE : View.VISIBLE}"
layout="@layout/voip_call_extra_actions"
bind:viewModel="@{viewModel}"/>

View file

@ -4,6 +4,10 @@
xmlns:app="http://schemas.android.com/apk/res-auto">
<data>
<import type="android.view.View" />
<variable
name="callViewModel"
type="org.linphone.ui.voip.viewmodel.CurrentCallViewModel" />
</data>
<androidx.coordinatorlayout.widget.CoordinatorLayout
@ -26,6 +30,7 @@
<LinearLayout
android:id="@+id/toasts_area"
android:visibility="@{callViewModel.pipMode ? View.INVISIBLE : View.VISIBLE}"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:orientation="vertical"