diff options
| author | 2024-10-08 02:45:37 +0000 | |
|---|---|---|
| committer | 2024-10-08 02:45:37 +0000 | |
| commit | 23f855335abe83ae97d2503b2761a68680d1b26b (patch) | |
| tree | 99b40cfae00336bc8609ae7962cc1eb4d4305650 | |
| parent | 34579ccce37c5b9f137f1e79bd030f140313860f (diff) | |
| parent | 3267e5259c7a15394a351b58880e06b08f340415 (diff) | |
Merge "Update app widget size when resized" into main
3 files changed, 61 insertions, 12 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/communal/ui/binder/CommunalAppWidgetHostViewBinder.kt b/packages/SystemUI/src/com/android/systemui/communal/ui/binder/CommunalAppWidgetHostViewBinder.kt index 5f421fd19550..ba96f4e56421 100644 --- a/packages/SystemUI/src/com/android/systemui/communal/ui/binder/CommunalAppWidgetHostViewBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/communal/ui/binder/CommunalAppWidgetHostViewBinder.kt @@ -17,19 +17,30 @@ package com.android.systemui.communal.ui.binder import android.content.Context +import android.os.Bundle import android.util.SizeF import android.view.View import android.view.ViewGroup import android.widget.FrameLayout +import androidx.compose.ui.unit.IntSize import androidx.core.view.doOnLayout +import com.android.app.tracing.coroutines.flow.flowOn import com.android.app.tracing.coroutines.launch +import com.android.systemui.Flags.communalWidgetResizing +import com.android.systemui.common.ui.view.onLayoutChanged import com.android.systemui.communal.domain.model.CommunalContentModel import com.android.systemui.communal.util.WidgetViewFactory import com.android.systemui.util.kotlin.DisposableHandles +import com.android.systemui.util.kotlin.toDp +import com.android.systemui.utils.coroutines.flow.conflatedCallbackFlow +import kotlin.coroutines.CoroutineContext import kotlin.coroutines.resume import kotlin.coroutines.suspendCoroutine import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.DisposableHandle +import kotlinx.coroutines.channels.awaitClose +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.distinctUntilChanged object CommunalAppWidgetHostViewBinder { private const val TAG = "CommunalAppWidgetHostViewBinder" @@ -37,9 +48,11 @@ object CommunalAppWidgetHostViewBinder { fun bind( context: Context, applicationScope: CoroutineScope, + mainContext: CoroutineContext, + backgroundContext: CoroutineContext, container: FrameLayout, model: CommunalContentModel.WidgetContent.Widget, - size: SizeF, + size: SizeF?, factory: WidgetViewFactory, ): DisposableHandle { val disposables = DisposableHandles() @@ -49,6 +62,22 @@ object CommunalAppWidgetHostViewBinder { val widget = factory.createWidget(context, model, size) waitForLayout(container) container.post { container.setView(widget) } + if (communalWidgetResizing()) { + // Update the app widget size in the background. + launch("$TAG#updateSize", backgroundContext) { + container.sizeFlow().flowOn(mainContext).distinctUntilChanged().collect { + (width, height) -> + widget.updateAppWidgetSize( + /* newOptions = */ Bundle(), + /* minWidth = */ width, + /* minHeight = */ height, + /* maxWidth = */ width, + /* maxHeight = */ height, + /* ignorePadding = */ true, + ) + } + } + } } disposables += DisposableHandle { loadingJob.cancel() } @@ -69,3 +98,13 @@ private fun ViewGroup.setView(view: View) { (view.parent as? ViewGroup)?.removeView(view) addView(view) } + +private fun View.sizeAsDp(): IntSize = IntSize(width.toDp(context), height.toDp(context)) + +private fun View.sizeFlow(): Flow<IntSize> = conflatedCallbackFlow { + if (isLaidOut && !isLayoutRequested) { + trySend(sizeAsDp()) + } + val disposable = onLayoutChanged { trySend(sizeAsDp()) } + awaitClose { disposable.dispose() } +} diff --git a/packages/SystemUI/src/com/android/systemui/communal/ui/view/layout/sections/CommunalAppWidgetSection.kt b/packages/SystemUI/src/com/android/systemui/communal/ui/view/layout/sections/CommunalAppWidgetSection.kt index 56b769e7bc13..2e12bad744f0 100644 --- a/packages/SystemUI/src/com/android/systemui/communal/ui/view/layout/sections/CommunalAppWidgetSection.kt +++ b/packages/SystemUI/src/com/android/systemui/communal/ui/view/layout/sections/CommunalAppWidgetSection.kt @@ -25,13 +25,17 @@ import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier import androidx.compose.ui.viewinterop.AndroidView import androidx.lifecycle.compose.collectAsStateWithLifecycle +import com.android.systemui.Flags.communalWidgetResizing import com.android.systemui.communal.domain.model.CommunalContentModel import com.android.systemui.communal.ui.binder.CommunalAppWidgetHostViewBinder import com.android.systemui.communal.ui.viewmodel.BaseCommunalViewModel import com.android.systemui.communal.util.WidgetViewFactory import com.android.systemui.dagger.qualifiers.Application +import com.android.systemui.dagger.qualifiers.Main +import com.android.systemui.dagger.qualifiers.UiBackground import com.android.systemui.res.R import javax.inject.Inject +import kotlin.coroutines.CoroutineContext import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.DisposableHandle @@ -39,6 +43,8 @@ class CommunalAppWidgetSection @Inject constructor( @Application private val applicationScope: CoroutineScope, + @Main private val mainContext: CoroutineContext, + @UiBackground private val backgroundContext: CoroutineContext, private val factory: WidgetViewFactory, ) { @@ -76,10 +82,12 @@ constructor( context = context, container = this, model = model, - size = size, + size = if (!communalWidgetResizing()) size else null, factory = factory, applicationScope = applicationScope, - ) + mainContext = mainContext, + backgroundContext = backgroundContext, + ), ) accessibilityDelegate = viewModel.widgetAccessibilityDelegate diff --git a/packages/SystemUI/src/com/android/systemui/communal/util/WidgetViewFactory.kt b/packages/SystemUI/src/com/android/systemui/communal/util/WidgetViewFactory.kt index cafa74faf1a1..07a7c7cba2fd 100644 --- a/packages/SystemUI/src/com/android/systemui/communal/util/WidgetViewFactory.kt +++ b/packages/SystemUI/src/com/android/systemui/communal/util/WidgetViewFactory.kt @@ -43,7 +43,7 @@ constructor( suspend fun createWidget( context: Context, model: CommunalContentModel.WidgetContent.Widget, - size: SizeF, + size: SizeF?, ): CommunalAppWidgetHostView = withContext("$TAG#createWidget", uiBgContext) { val view = @@ -54,14 +54,16 @@ constructor( // Instead of setting the view as the listener directly, we wrap the view in a delegate // which ensures the callbacks always get called on the main thread. appWidgetHost.setListener(model.appWidgetId, listenerFactory.create(view)) - view.updateAppWidgetSize( - /* newOptions = */ Bundle(), - /* minWidth = */ size.width.toInt(), - /* minHeight = */ size.height.toInt(), - /* maxWidth = */ size.width.toInt(), - /* maxHeight = */ size.height.toInt(), - /* ignorePadding = */ true, - ) + if (size != null) { + view.updateAppWidgetSize( + /* newOptions = */ Bundle(), + /* minWidth = */ size.width.toInt(), + /* minHeight = */ size.height.toInt(), + /* maxWidth = */ size.width.toInt(), + /* maxHeight = */ size.height.toInt(), + /* ignorePadding = */ true, + ) + } view } |