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

Commit 6a9beab9 authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "[flexiglass] Light reveal scrim" into main

parents 72a94421 624f5e62
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -179,6 +179,12 @@ fun SceneContainer(
                }
            }
    ) {
        SceneRevealScrim(
            viewModel = viewModel.lightRevealScrim,
            wallpaperViewModel = viewModel.wallpaperViewModel,
            modifier = Modifier.fillMaxSize(),
        )

        SceneTransitionLayout(
            state = state,
            modifier = modifier.fillMaxSize(),
+45 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2025 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.systemui.scene.ui.composable

import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.viewinterop.AndroidView
import com.android.systemui.keyguard.ui.binder.LightRevealScrimViewBinder
import com.android.systemui.keyguard.ui.viewmodel.LightRevealScrimViewModel
import com.android.systemui.statusbar.LightRevealScrim
import com.android.systemui.wallpapers.ui.viewmodel.WallpaperViewModel

@Composable
fun SceneRevealScrim(
    viewModel: LightRevealScrimViewModel,
    wallpaperViewModel: WallpaperViewModel,
    modifier: Modifier = Modifier,
) {
    AndroidView(
        factory = { context ->
            LightRevealScrim(context).apply {
                LightRevealScrimViewBinder.bind(
                    revealScrim = this,
                    viewModel = viewModel,
                    wallpaperViewModel = wallpaperViewModel,
                )
            }
        },
        modifier = modifier,
    )
}
+4 −0
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@ import com.android.compose.animation.scene.UserAction
import com.android.compose.animation.scene.UserActionResult
import com.android.systemui.classifier.Classifier
import com.android.systemui.classifier.domain.interactor.FalsingInteractor
import com.android.systemui.keyguard.ui.viewmodel.LightRevealScrimViewModel
import com.android.systemui.lifecycle.ExclusiveActivatable
import com.android.systemui.lifecycle.Hydrator
import com.android.systemui.power.domain.interactor.PowerInteractor
@@ -41,6 +42,7 @@ import com.android.systemui.shade.domain.interactor.ShadeInteractor
import com.android.systemui.shade.shared.model.ShadeMode
import com.android.systemui.statusbar.domain.interactor.RemoteInputInteractor
import com.android.systemui.statusbar.notification.stack.ui.view.SharedNotificationContainer
import com.android.systemui.wallpapers.ui.viewmodel.WallpaperViewModel
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
@@ -62,6 +64,8 @@ constructor(
    private val splitEdgeDetector: SplitEdgeDetector,
    private val logger: SceneLogger,
    hapticsViewModelFactory: SceneContainerHapticsViewModel.Factory,
    val lightRevealScrim: LightRevealScrimViewModel,
    val wallpaperViewModel: WallpaperViewModel,
    @Assisted view: View,
    @Assisted private val motionEventHandlerReceiver: (MotionEventHandler?) -> Unit,
) : ExclusiveActivatable() {
+22 −20
Original line number Diff line number Diff line
@@ -84,7 +84,7 @@ object LiftReveal : LightRevealEffect {
                scrim.width * initialWidthMultiplier + -scrim.width * ovalWidthIncreaseAmount,
                scrim.height * OVAL_INITIAL_TOP_PERCENT - scrim.height * interpolatedAmount,
                scrim.width * (1f - initialWidthMultiplier) + scrim.width * ovalWidthIncreaseAmount,
                scrim.height * OVAL_INITIAL_BOTTOM_PERCENT + scrim.height * interpolatedAmount
                scrim.height * OVAL_INITIAL_BOTTOM_PERCENT + scrim.height * interpolatedAmount,
            )
        }
    }
@@ -98,7 +98,7 @@ data class LinearLightRevealEffect(private val isVertical: Boolean) : LightRevea
            /* controlX1= */ 0.4f,
            /* controlY1= */ 0f,
            /* controlX2= */ 0.2f,
            /* controlY2= */ 1f
            /* controlY2= */ 1f,
        )

    override fun setRevealAmountOnScrim(amount: Float, scrim: LightRevealScrim) {
@@ -109,14 +109,14 @@ data class LinearLightRevealEffect(private val isVertical: Boolean) : LightRevea
        scrim.startColorAlpha =
            getPercentPastThreshold(
                1 - interpolatedAmount,
                threshold = 1 - START_COLOR_REVEAL_PERCENTAGE
                threshold = 1 - START_COLOR_REVEAL_PERCENTAGE,
            )

        scrim.revealGradientEndColorAlpha =
            1f -
                getPercentPastThreshold(
                    interpolatedAmount,
                    threshold = REVEAL_GRADIENT_END_COLOR_ALPHA_START_PERCENTAGE
                    threshold = REVEAL_GRADIENT_END_COLOR_ALPHA_START_PERCENTAGE,
                )

        // Start changing gradient bounds later to avoid harsh gradient in the beginning
@@ -127,14 +127,14 @@ data class LinearLightRevealEffect(private val isVertical: Boolean) : LightRevea
                left = scrim.viewWidth / 2 - (scrim.viewWidth / 2) * gradientBoundsAmount,
                top = 0f,
                right = scrim.viewWidth / 2 + (scrim.viewWidth / 2) * gradientBoundsAmount,
                bottom = scrim.viewHeight.toFloat()
                bottom = scrim.viewHeight.toFloat(),
            )
        } else {
            scrim.setRevealGradientBounds(
                left = 0f,
                top = scrim.viewHeight / 2 - (scrim.viewHeight / 2) * gradientBoundsAmount,
                right = scrim.viewWidth.toFloat(),
                bottom = scrim.viewHeight / 2 + (scrim.viewHeight / 2) * gradientBoundsAmount
                bottom = scrim.viewHeight / 2 + (scrim.viewHeight / 2) * gradientBoundsAmount,
            )
        }
    }
@@ -166,7 +166,7 @@ data class LinearSideLightRevealEffect(private val isVertical: Boolean) : LightR
            1f -
                getPercentPastThreshold(
                    amount,
                    threshold = REVEAL_GRADIENT_END_COLOR_ALPHA_START_PERCENTAGE
                    threshold = REVEAL_GRADIENT_END_COLOR_ALPHA_START_PERCENTAGE,
                )

        val gradientBoundsAmount = lerp(GRADIENT_START_BOUNDS_PERCENTAGE, 1f, amount)
@@ -175,14 +175,14 @@ data class LinearSideLightRevealEffect(private val isVertical: Boolean) : LightR
                left = -(scrim.viewWidth) * gradientBoundsAmount,
                top = -(scrim.viewHeight) * gradientBoundsAmount,
                right = (scrim.viewWidth) * gradientBoundsAmount,
                bottom = (scrim.viewHeight) + (scrim.viewHeight) * gradientBoundsAmount
                bottom = (scrim.viewHeight) + (scrim.viewHeight) * gradientBoundsAmount,
            )
        } else {
            scrim.setRevealGradientBounds(
                left = -(scrim.viewWidth) * gradientBoundsAmount,
                top = -(scrim.viewHeight) * gradientBoundsAmount,
                right = (scrim.viewWidth) + (scrim.viewWidth) * gradientBoundsAmount,
                bottom = (scrim.viewHeight) * gradientBoundsAmount
                bottom = (scrim.viewHeight) * gradientBoundsAmount,
            )
        }
    }
@@ -212,7 +212,7 @@ data class CircleReveal(
    /** Radius of initial state of circle reveal */
    val startRadius: Int,
    /** Radius of end state of circle reveal */
    val endRadius: Int
    val endRadius: Int,
) : LightRevealEffect {
    override fun setRevealAmountOnScrim(amount: Float, scrim: LightRevealScrim) {
        // reveal amount updates already have an interpolator, so we intentionally use the
@@ -225,7 +225,7 @@ data class CircleReveal(
            centerX - radius /* left */,
            centerY - radius /* top */,
            centerX + radius /* right */,
            centerY + radius /* bottom */
            centerY + radius, /* bottom */
        )
    }
}
@@ -259,7 +259,7 @@ data class PowerButtonReveal(
                    powerButtonY - height * interpolatedAmount,
                    width * (1f + OFF_SCREEN_START_AMOUNT) +
                        width * INCREASE_MULTIPLIER * interpolatedAmount,
                    powerButtonY + height * interpolatedAmount
                    powerButtonY + height * interpolatedAmount,
                )
            } else if (rotation == RotationUtils.ROTATION_LANDSCAPE) {
                setRevealGradientBounds(
@@ -268,7 +268,7 @@ data class PowerButtonReveal(
                        height * INCREASE_MULTIPLIER * interpolatedAmount,
                    powerButtonY + width * interpolatedAmount,
                    (-height * OFF_SCREEN_START_AMOUNT) +
                        height * INCREASE_MULTIPLIER * interpolatedAmount
                        height * INCREASE_MULTIPLIER * interpolatedAmount,
                )
            } else {
                // RotationUtils.ROTATION_SEASCAPE
@@ -278,7 +278,7 @@ data class PowerButtonReveal(
                        height * INCREASE_MULTIPLIER * interpolatedAmount,
                    (width - powerButtonY) + width * interpolatedAmount,
                    height * (1f + OFF_SCREEN_START_AMOUNT) +
                        height * INCREASE_MULTIPLIER * interpolatedAmount
                        height * INCREASE_MULTIPLIER * interpolatedAmount,
                )
            }
        }
@@ -296,9 +296,9 @@ class LightRevealScrim
@JvmOverloads
constructor(
    context: Context?,
    attrs: AttributeSet?,
    attrs: AttributeSet? = null,
    initialWidth: Int? = null,
    initialHeight: Int? = null
    initialHeight: Int? = null,
) : View(context, attrs) {

    private val logString = this::class.simpleName!! + "@" + hashCode()
@@ -322,8 +322,9 @@ constructor(
                revealEffect.setRevealAmountOnScrim(value, this)
                updateScrimOpaque()
                TrackTracer.instantForGroup(
                    "scrim", { "light_reveal_amount $logString" },
                    (field * 100).toInt()
                    "scrim",
                    { "light_reveal_amount $logString" },
                    (field * 100).toInt(),
                )
                invalidate()
            }
@@ -440,7 +441,7 @@ constructor(
                    1f,
                    intArrayOf(Color.TRANSPARENT, Color.WHITE),
                    floatArrayOf(0f, 1f),
                    Shader.TileMode.CLAMP
                    Shader.TileMode.CLAMP,
                )

            // SRC_OVER ensures that we draw the semitransparent pixels over other views in the same
@@ -466,6 +467,7 @@ constructor(
        viewWidth = measuredWidth
        viewHeight = measuredHeight
    }

    /**
     * Sets bounds for the transparent oval gradient that reveals the views below the scrim. This is
     * simply a helper method that sets [revealGradientCenter], [revealGradientWidth], and
@@ -513,7 +515,7 @@ constructor(
        gradientPaint.colorFilter =
            PorterDuffColorFilter(
                getColorWithAlpha(revealGradientEndColor, revealGradientEndColorAlpha),
                PorterDuff.Mode.MULTIPLY
                PorterDuff.Mode.MULTIPLY,
            )
    }
}
+25 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2025 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.systemui.keyguard.ui.viewmodel

import com.android.systemui.keyguard.domain.interactor.lightRevealScrimInteractor
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.Kosmos.Fixture

val Kosmos.lightRevealScrimViewModel by Fixture {
    LightRevealScrimViewModel(interactor = lightRevealScrimInteractor)
}
Loading