Skip to content

Commit

Permalink
Merge pull request #3199 from element-hq/feature/bma/improvePip
Browse files Browse the repository at this point in the history
Improve pip and add feature flag.
  • Loading branch information
bmarty authored Jul 16, 2024
2 parents 2ff5fa6 + 9c42c2d commit 544b4a1
Show file tree
Hide file tree
Showing 11 changed files with 66 additions and 3 deletions.
1 change: 1 addition & 0 deletions features/call/impl/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ dependencies {
implementation(projects.libraries.architecture)
implementation(projects.libraries.core)
implementation(projects.libraries.designsystem)
implementation(projects.libraries.featureflag.api)
implementation(projects.libraries.matrix.impl)
implementation(projects.libraries.matrixui)
implementation(projects.libraries.network)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,16 @@

package io.element.android.features.call.impl.pip

import androidx.compose.ui.tooling.preview.PreviewParameterProvider

open class PictureInPictureStateProvider : PreviewParameterProvider<PictureInPictureState> {
override val values: Sequence<PictureInPictureState>
get() = sequenceOf(
aPictureInPictureState(supportPip = true),
aPictureInPictureState(supportPip = true, isInPictureInPicture = true),
)
}

fun aPictureInPictureState(
supportPip: Boolean = false,
isInPictureInPicture: Boolean = false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ import com.squareup.anvil.annotations.ContributesBinding
import io.element.android.libraries.core.bool.orFalse
import io.element.android.libraries.di.AppScope
import io.element.android.libraries.di.ApplicationContext
import io.element.android.libraries.featureflag.api.FeatureFlagService
import io.element.android.libraries.featureflag.api.FeatureFlags
import kotlinx.coroutines.runBlocking
import javax.inject.Inject

interface PipSupportProvider {
Expand All @@ -34,9 +37,15 @@ interface PipSupportProvider {
@ContributesBinding(AppScope::class)
class DefaultPipSupportProvider @Inject constructor(
@ApplicationContext private val context: Context,
private val featureFlagService: FeatureFlagService,
) : PipSupportProvider {
override fun isPipSupported(): Boolean {
val hasSystemFeaturePip = context.packageManager?.hasSystemFeature(PackageManager.FEATURE_PICTURE_IN_PICTURE).orFalse()
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && hasSystemFeaturePip
val isSupportedByTheOs = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O &&
context.packageManager?.hasSystemFeature(PackageManager.FEATURE_PICTURE_IN_PICTURE).orFalse()
return if (isSupportedByTheOs) {
runBlocking { featureFlagService.isFeatureEnabled(FeatureFlags.PictureInPicture) }
} else {
false
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import io.element.android.compound.tokens.generated.CompoundIcons
import io.element.android.features.call.impl.R
import io.element.android.features.call.impl.pip.PictureInPictureEvents
import io.element.android.features.call.impl.pip.PictureInPictureState
import io.element.android.features.call.impl.pip.PictureInPictureStateProvider
import io.element.android.features.call.impl.pip.aPictureInPictureState
import io.element.android.features.call.impl.utils.WebViewWidgetMessageInterceptor
import io.element.android.libraries.architecture.AsyncData
Expand Down Expand Up @@ -81,7 +82,7 @@ internal fun CallScreenView(
title = { Text(stringResource(R.string.element_call)) },
navigationIcon = {
BackButton(
imageVector = CompoundIcons.Close(),
imageVector = if (pipState.supportPip) CompoundIcons.ArrowLeft() else CompoundIcons.Close(),
onClick = ::handleBack,
)
}
Expand Down Expand Up @@ -195,3 +196,15 @@ internal fun CallScreenViewPreview(
requestPermissions = { _, _ -> },
)
}

@PreviewsDayNight
@Composable
internal fun CallScreenPipViewPreview(
@PreviewParameter(PictureInPictureStateProvider::class) state: PictureInPictureState,
) = ElementPreview {
CallScreenView(
state = aCallScreenState(),
pipState = state,
requestPermissions = { _, _ -> },
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity
import androidx.compose.runtime.mutableStateOf
import androidx.core.content.IntentCompat
import androidx.lifecycle.Lifecycle
import io.element.android.features.call.api.CallType
import io.element.android.features.call.impl.DefaultElementCallEntryPoint
import io.element.android.features.call.impl.di.CallBindings
Expand All @@ -41,6 +42,7 @@ import io.element.android.features.call.impl.utils.CallIntentDataParser
import io.element.android.libraries.architecture.bindings
import io.element.android.libraries.designsystem.theme.ElementThemeApp
import io.element.android.libraries.preferences.api.store.AppPreferencesStore
import timber.log.Timber
import javax.inject.Inject

class ElementCallActivity : AppCompatActivity(), CallScreenNavigator {
Expand All @@ -63,6 +65,8 @@ class ElementCallActivity : AppCompatActivity(), CallScreenNavigator {
private var isDarkMode = false
private val webViewTarget = mutableStateOf<CallType?>(null)

private var eventSink: ((CallScreenEvents) -> Unit)? = null

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

Expand Down Expand Up @@ -91,6 +95,7 @@ class ElementCallActivity : AppCompatActivity(), CallScreenNavigator {
val pipState = pictureInPicturePresenter.present()
ElementThemeApp(appPreferencesStore) {
val state = presenter.present()
eventSink = state.eventSink
CallScreenView(
state = state,
pipState = pipState,
Expand All @@ -111,6 +116,11 @@ class ElementCallActivity : AppCompatActivity(), CallScreenNavigator {
override fun onPictureInPictureModeChanged(isInPictureInPictureMode: Boolean, newConfig: Configuration) {
super.onPictureInPictureModeChanged(isInPictureInPictureMode, newConfig)
pictureInPicturePresenter.onPictureInPictureModeChanged(isInPictureInPictureMode)

if (!isInPictureInPictureMode && !lifecycle.currentState.isAtLeast(Lifecycle.State.STARTED)) {
Timber.d("Exiting PiP mode: Hangup the call")
eventSink?.invoke(CallScreenEvents.Hangup)
}
}

override fun onNewIntent(intent: Intent) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,4 +113,11 @@ enum class FeatureFlags(
defaultValue = { true },
isFinished = false,
),
PictureInPicture(
key = "feature.pictureInPicture",
title = "Picture in Picture for Calls",
description = "Allow the Call to be rendered in PiP mode",
defaultValue = { it.buildType != BuildType.RELEASE },
isFinished = false,
),
}
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ class KonsistPreviewTest {
"AsyncIndicatorLoadingPreview",
"BloomInitialsPreview",
"BloomPreview",
"CallScreenPipViewPreview",
"ColorAliasesPreview",
"DefaultRoomListTopBarWithIndicatorPreview",
"GradientFloatingActionButtonCircleShapePreview",
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 544b4a1

Please sign in to comment.