Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 33fbe715 authored by Jordan Demeulenaere's avatar Jordan Demeulenaere
Browse files

Recreate footer actions when density was changed

Bug: 317317814
Test: Manual, changed display size settings and observed that the footer
 actions had a correct size.
Flag: N/A
Change-Id: Ide89df32fd3b69dc0eb02ce6a0f9e354457c26d5
parent 79b8a00c
Loading
Loading
Loading
Loading
+96 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.compose.ui.platform

import android.content.Context
import android.content.res.Configuration
import android.util.AttributeSet
import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.ui.platform.AbstractComposeView

/**
 * A ComposeView that recreates its composition if the display size or font scale was changed.
 *
 * TODO(b/317317814): Remove this workaround.
 */
class DensityAwareComposeView(context: Context) : OpenComposeView(context) {
    private var lastDensityDpi: Int = -1
    private var lastFontScale: Float = -1f

    override fun onAttachedToWindow() {
        super.onAttachedToWindow()

        val configuration = context.resources.configuration
        lastDensityDpi = configuration.densityDpi
        lastFontScale = configuration.fontScale
    }

    override fun dispatchConfigurationChanged(newConfig: Configuration) {
        super.dispatchConfigurationChanged(newConfig)

        // If the density or font scale changed, we dispose then recreate the composition. Note that
        // we do this here after dispatching the new configuration to children (instead of doing
        // this in onConfigurationChanged()) because the new configuration should first be
        // dispatched to the AndroidComposeView that holds the current density before we recreate
        // the composition.
        val densityDpi = newConfig.densityDpi
        val fontScale = newConfig.fontScale
        if (densityDpi != lastDensityDpi || fontScale != lastFontScale) {
            lastDensityDpi = densityDpi
            lastFontScale = fontScale

            disposeComposition()
            if (isAttachedToWindow) {
                createComposition()
            }
        }
    }
}

/** A fork of [androidx.compose.ui.platform.ComposeView] that is open and can be subclassed. */
open class OpenComposeView
internal constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) :
    AbstractComposeView(context, attrs, defStyleAttr) {

    private val content = mutableStateOf<(@Composable () -> Unit)?>(null)

    @Suppress("RedundantVisibilityModifier")
    protected override var shouldCreateCompositionOnAttachedToWindow: Boolean = false

    @Composable
    override fun Content() {
        content.value?.invoke()
    }

    override fun getAccessibilityClassName(): CharSequence {
        return javaClass.name
    }

    /**
     * Set the Jetpack Compose UI content for this view. Initial composition will occur when the
     * view becomes attached to a window or when [createComposition] is called, whichever comes
     * first.
     */
    fun setContent(content: @Composable () -> Unit) {
        shouldCreateCompositionOnAttachedToWindow = true
        this.content.value = content
        if (isAttachedToWindow) {
            createComposition()
        }
    }
}
+2 −1
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.lifecycle.LifecycleOwner
import com.android.compose.theme.PlatformTheme
import com.android.compose.ui.platform.DensityAwareComposeView
import com.android.systemui.common.ui.compose.windowinsets.CutoutLocation
import com.android.systemui.common.ui.compose.windowinsets.DisplayCutout
import com.android.systemui.common.ui.compose.windowinsets.DisplayCutoutProvider
@@ -84,7 +85,7 @@ object ComposeFacade : BaseComposeFacade {
        viewModel: FooterActionsViewModel,
        qsVisibilityLifecycleOwner: LifecycleOwner,
    ): View {
        return ComposeView(context).apply {
        return DensityAwareComposeView(context).apply {
            setContent { PlatformTheme { FooterActions(viewModel, qsVisibilityLifecycleOwner) } }
        }
    }