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

Commit 33a49561 authored by Android Build Coastguard Worker's avatar Android Build Coastguard Worker
Browse files

Snap for 12923841 from 2ed63f27 to 25Q2-release

Change-Id: Ie3a0efc27830f3400aaefd04aecf857dfd09ff3e
parents be1055f1 2ed63f27
Loading
Loading
Loading
Loading
+6 −4
Original line number Diff line number Diff line
@@ -37,11 +37,12 @@ import com.android.launcher3.icons.BitmapInfo
import com.android.launcher3.icons.IconThemeController
import com.android.launcher3.icons.MonochromeIconFactory
import com.android.launcher3.icons.ThemedBitmap
import com.android.launcher3.icons.mono.ThemedIconDrawable.Companion.getColors
import java.nio.ByteBuffer

@TargetApi(Build.VERSION_CODES.TIRAMISU)
class MonoIconThemeController : IconThemeController {
class MonoIconThemeController(
    private val colorProvider: (Context) -> IntArray = ThemedIconDrawable.Companion::getColors
) : IconThemeController {

    override fun createThemedBitmap(
        icon: AdaptiveIconDrawable,
@@ -55,6 +56,7 @@ class MonoIconThemeController : IconThemeController {
            return MonoThemedBitmap(
                factory.createIconBitmap(mono, scale, BaseIconFactory.MODE_ALPHA),
                factory.whiteShadowLayer,
                colorProvider,
            )
        }
        return null
@@ -92,7 +94,7 @@ class MonoIconThemeController : IconThemeController {
            monoBitmap.recycle()
            monoBitmap = hwMonoBitmap
        }
        return MonoThemedBitmap(monoBitmap, factory.whiteShadowLayer)
        return MonoThemedBitmap(monoBitmap, factory.whiteShadowLayer, colorProvider)
    }

    override fun createThemedAdaptiveIcon(
@@ -100,7 +102,7 @@ class MonoIconThemeController : IconThemeController {
        originalIcon: AdaptiveIconDrawable,
        info: BitmapInfo?,
    ): AdaptiveIconDrawable? {
        val colors = getColors(context)
        val colors = colorProvider(context)
        originalIcon.mutate()
        var monoDrawable = originalIcon.monochrome?.apply { setTint(colors[1]) }

+6 −2
Original line number Diff line number Diff line
@@ -24,10 +24,14 @@ import com.android.launcher3.icons.ThemedBitmap
import com.android.launcher3.icons.mono.ThemedIconDrawable.ThemedConstantState
import java.nio.ByteBuffer

class MonoThemedBitmap(val mono: Bitmap, private val whiteShadowLayer: Bitmap) : ThemedBitmap {
class MonoThemedBitmap(
    val mono: Bitmap,
    private val whiteShadowLayer: Bitmap,
    private val colorProvider: (Context) -> IntArray = ThemedIconDrawable.Companion::getColors,
) : ThemedBitmap {

    override fun newDrawable(info: BitmapInfo, context: Context): FastBitmapDrawable {
        val colors = ThemedIconDrawable.getColors(context)
        val colors = colorProvider(context)
        return ThemedConstantState(info, mono, whiteShadowLayer, colors[0], colors[1]).newDrawable()
    }

+13 −2
Original line number Diff line number Diff line
@@ -58,8 +58,19 @@ interface GestureContext {
    val dragOffset: Float
}

/**
 * [GestureContext] with a mutable [dragOffset].
 *
 * The implementation class defines whether the [direction] is updated accordingly.
 */
interface MutableDragOffsetGestureContext : GestureContext {
    /** The gesture distance of the current gesture, in pixels. */
    override var dragOffset: Float
}

/** [GestureContext] implementation for manually set values. */
class ProvidedGestureContext(direction: InputDirection, dragOffset: Float) : GestureContext {
class ProvidedGestureContext(dragOffset: Float, direction: InputDirection) :
    MutableDragOffsetGestureContext {
    override var direction by mutableStateOf(direction)
    override var dragOffset by mutableFloatStateOf(dragOffset)
}
@@ -79,7 +90,7 @@ class DistanceGestureContext(
    initialDragOffset: Float,
    initialDirection: InputDirection,
    directionChangeSlop: Float,
) : GestureContext {
) : MutableDragOffsetGestureContext {
    init {
        require(directionChangeSlop > 0) {
            "directionChangeSlop must be greater than 0, was $directionChangeSlop"
+132 −35
Original line number Diff line number Diff line
@@ -18,17 +18,22 @@ package com.android.mechanics.debug

import androidx.compose.foundation.layout.Spacer
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.snapshotFlow
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.composed
import androidx.compose.ui.draw.drawBehind
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.drawscope.ContentDrawScope
import androidx.compose.ui.graphics.drawscope.DrawScope
import androidx.compose.ui.node.DrawModifierNode
import androidx.compose.ui.node.ModifierNodeElement
import androidx.compose.ui.node.ObserverModifierNode
import androidx.compose.ui.node.observeReads
import androidx.compose.ui.platform.InspectorInfo
import androidx.compose.ui.unit.dp
import androidx.compose.ui.util.fastForEachIndexed
import com.android.mechanics.MotionValue
@@ -77,12 +82,10 @@ fun DebugMotionValueVisualization(
 * @param inputRange The range of the input (x) axis
 * @param outputRange The range of the output (y) axis.
 */
@Composable
fun Modifier.debugMotionSpecGraph(
    spec: MotionSpec,
    inputRange: ClosedFloatingPointRange<Float>,
    outputRange: ClosedFloatingPointRange<Float> =
        remember(spec, inputRange) { spec.computeOutputValueRange(inputRange) },
    outputRange: ClosedFloatingPointRange<Float>,
): Modifier = drawBehind {
    drawAxis(Color.Gray)
    if (spec.isUnidirectional) {
@@ -111,35 +114,18 @@ fun Modifier.debugMotionValueGraph(
    motionValue: MotionValue,
    color: Color,
    inputRange: ClosedFloatingPointRange<Float>,
    outputRange: ClosedFloatingPointRange<Float> =
        remember(motionValue.spec, inputRange) {
            motionValue.spec.computeOutputValueRange(inputRange)
        },
    outputRange: ClosedFloatingPointRange<Float>,
    historySize: Int = 100,
): Modifier = composed {
    val inspector = remember(motionValue) { motionValue.debugInspector() }

    val history = remember { mutableStateListOf<FrameData>() }

    LaunchedEffect(inspector, history) {
        snapshotFlow { inspector.frame }
            .collect {
                history.add(it)
                if (history.size > historySize) {
                    history.removeFirst()
                }
            }
    }

    DisposableEffect(inspector) { onDispose { inspector.dispose() } }

    this.drawBehind { drawInputOutputTrail(history, inputRange, outputRange, color) }
}
): Modifier =
    this then DebugMotionValueGraphElement(motionValue, color, inputRange, outputRange, historySize)

private val MotionSpec.isUnidirectional: Boolean
    get() = maxDirection == minDirection

private fun MotionSpec.computeOutputValueRange(
/**
 * Utility to compute the min/max output values of the spec for the given input.
 *
 * Note: this only samples at breakpoint locations. For segment mappings that produce smaller/larger
 * values in between two breakpoints, this method might might not produce a correct result.
 */
fun MotionSpec.computeOutputValueRange(
    inputRange: ClosedFloatingPointRange<Float>
): ClosedFloatingPointRange<Float> {
    return if (isUnidirectional) {
@@ -155,7 +141,13 @@ private fun MotionSpec.computeOutputValueRange(
    }
}

private fun DirectionalMotionSpec.computeOutputValueRange(
/**
 * Utility to compute the min/max output values of the spec for the given input.
 *
 * Note: this only samples at breakpoint locations. For segment mappings that produce smaller/larger
 * values in between two breakpoints, this method might might not produce a correct result.
 */
fun DirectionalMotionSpec.computeOutputValueRange(
    inputRange: ClosedFloatingPointRange<Float>
): ClosedFloatingPointRange<Float> {

@@ -179,6 +171,111 @@ private fun DirectionalMotionSpec.computeOutputValueRange(
    return samples.min()..samples.max()
}

private data class DebugMotionValueGraphElement(
    val motionValue: MotionValue,
    val color: Color,
    val inputRange: ClosedFloatingPointRange<Float>,
    val outputRange: ClosedFloatingPointRange<Float>,
    val historySize: Int,
) : ModifierNodeElement<DebugMotionValueGraphNode>() {

    init {
        require(historySize > 0)
    }

    override fun create() =
        DebugMotionValueGraphNode(motionValue, color, inputRange, outputRange, historySize)

    override fun update(node: DebugMotionValueGraphNode) {
        node.motionValue = motionValue
        node.color = color
        node.inputRange = inputRange
        node.outputRange = outputRange
        node.historySize = historySize
    }

    override fun InspectorInfo.inspectableProperties() {
        // intentionally empty
    }
}

private class DebugMotionValueGraphNode(
    motionValue: MotionValue,
    var color: Color,
    var inputRange: ClosedFloatingPointRange<Float>,
    var outputRange: ClosedFloatingPointRange<Float>,
    historySize: Int,
) : DrawModifierNode, ObserverModifierNode, Modifier.Node() {

    private var debugInspector by mutableStateOf<DebugInspector?>(null)
    private val history = mutableStateListOf<FrameData>()

    var historySize = historySize
        set(value) {
            field = value

            if (history.size > value) {
                history.removeRange(0, value - historySize)
            }
        }

    var motionValue = motionValue
        set(value) {
            if (value != field) {
                disposeDebugInspector()
                field = value

                if (isAttached) {
                    acquireDebugInspector()
                }
            }
        }

    override fun onAttach() {
        acquireDebugInspector()
    }

    override fun onDetach() {
        disposeDebugInspector()
    }

    private fun acquireDebugInspector() {
        debugInspector = motionValue.debugInspector()
        observeFrameAndAddToHistory()
    }

    private fun disposeDebugInspector() {
        debugInspector?.dispose()
        debugInspector = null
        history.clear()
    }

    override fun ContentDrawScope.draw() {
        drawInputOutputTrail(history, inputRange, outputRange, color)
        drawContent()
    }

    private fun observeFrameAndAddToHistory() {
        var lastFrame: FrameData? = null

        observeReads { lastFrame = debugInspector?.frame }

        lastFrame?.also {
            history.add(it)
            if (history.size > historySize) {
                history.removeFirst()
            }
        }
    }

    override fun onObservedReadsChanged() {
        observeFrameAndAddToHistory()
    }
}

private val MotionSpec.isUnidirectional: Boolean
    get() = maxDirection == minDirection

private fun DrawScope.mapPointInInputToX(
    input: Float,
    inputRange: ClosedFloatingPointRange<Float>,