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

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

Snap for 13503953 from ff67aee7 to 25Q3-release

Change-Id: I1a0b74bdbfdd78c24b8aa5eeb3722f8d80bd162b
parents 435b077f ff67aee7
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -50,6 +50,7 @@ interface DisplayLibComponent {

    val displayRepository: DisplayRepository
    val displaysWithDecorationsRepository: DisplaysWithDecorationsRepository
    val displaysWithDecorationsRepositoryCompat: DisplaysWithDecorationsRepositoryCompat
}

@Module
+129 −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.app.displaylib

import com.android.internal.annotations.GuardedBy
import java.util.concurrent.ConcurrentHashMap
import javax.inject.Inject
import javax.inject.Singleton
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.launch
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
import kotlinx.coroutines.withContext

/** Listener for display system decorations changes. */
interface DisplayDecorationListener {
    /** Called when system decorations should be added to the display.* */
    fun onDisplayAddSystemDecorations(displayId: Int)

    /** Called when a display is removed. */
    fun onDisplayRemoved(displayId: Int)

    /** Called when system decorations should be removed from the display. */
    fun onDisplayRemoveSystemDecorations(displayId: Int)
}

/**
 * This class is a compatibility layer that allows to register and unregister listeners for display
 * decorations changes. It uses a [DisplaysWithDecorationsRepository] to get the current list of
 * displays with decorations and notifies the listeners when the list changes.
 */
@Singleton
class DisplaysWithDecorationsRepositoryCompat
@Inject
constructor(
    private val bgApplicationScope: CoroutineScope,
    private val displayRepository: DisplaysWithDecorationsRepository,
) {

    private val mutex = Mutex()
    private var collectorJob: Job? = null
    private val displayDecorationListenersWithDispatcher =
        ConcurrentHashMap<DisplayDecorationListener, CoroutineDispatcher>()

    /**
     * Registers a [DisplayDecorationListener] to be notified when the list of displays with
     * decorations changes.
     *
     * @param listener The listener to register.
     * @param dispatcher The dispatcher to use when notifying the listener.
     */
    fun registerDisplayDecorationListener(
        listener: DisplayDecorationListener,
        dispatcher: CoroutineDispatcher,
    ) {
        bgApplicationScope.launch {
            mutex.withLock {
                displayDecorationListenersWithDispatcher[listener] = dispatcher
                // Emit all the existing displays with decorations when registering.
                displayRepository.displayIdsWithSystemDecorations.value.forEach { displayId ->
                    withContext(dispatcher) { listener.onDisplayAddSystemDecorations(displayId) }
                }
                startCollectingIfNeeded()
            }
        }
    }

    /**
     * Unregisters a [DisplayDecorationListener].
     *
     * @param listener The listener to unregister.
     */
    fun unregisterDisplayDecorationListener(listener: DisplayDecorationListener) {
        bgApplicationScope.launch {
            mutex.withLock {
                displayDecorationListenersWithDispatcher.remove(listener)
                // stop collecting if no listeners
                if (displayDecorationListenersWithDispatcher.isEmpty()) {
                    collectorJob?.cancel()
                    collectorJob = null
                }
            }
        }
    }

    @GuardedBy("mutex")
    private fun startCollectingIfNeeded() {
        if (collectorJob?.isActive == true) {
            return
        }
        var oldDisplays: Set<Int> = displayRepository.displayIdsWithSystemDecorations.value
        collectorJob =
            bgApplicationScope.launch {
                displayRepository.displayIdsWithSystemDecorations.collect { currentDisplays ->
                    val previous = oldDisplays
                    oldDisplays = currentDisplays

                    val newDisplaysWithDecorations = currentDisplays - previous
                    val removedDisplays = previous - currentDisplays
                    displayDecorationListenersWithDispatcher.forEach { (listener, dispatcher) ->
                        withContext(dispatcher) {
                            newDisplaysWithDecorations.forEach { displayId ->
                                listener.onDisplayAddSystemDecorations(displayId)
                            }
                            removedDisplays.forEach { displayId ->
                                listener.onDisplayRemoveSystemDecorations(displayId)
                            }
                        }
                    }
                }
            }
    }
}
+28 −17
Original line number Diff line number Diff line
@@ -435,7 +435,7 @@ internal abstract class Computations : CurrentFrameInput, LastFrameState, Static
                    var guaranteeState = lastGuaranteeState
                    var springState = lastSpringState
                    var springParameters = lastAnimation.springParameters
                    var hasJumped = false
                    var initialSpringVelocity = directMappedVelocity

                    var segmentIndex = sourceIndex
                    while (segmentIndex != targetIndex) {
@@ -481,6 +481,13 @@ internal abstract class Computations : CurrentFrameInput, LastFrameState, Static
                                guaranteeState.updatedSpringParameters(lastBreakpoint)
                        }

                        springState =
                            springState.calculateUpdatedState(
                                nextBreakpointCrossTime - lastAnimationTime,
                                springParameters,
                            )
                        lastAnimationTime = nextBreakpointCrossTime

                        val mappingBefore = mappings[segmentIndex]
                        val beforeBreakpoint = mappingBefore.map(nextBreakpoint.position)
                        val mappingAfter = mappings[segmentIndex + directionOffset]
@@ -488,7 +495,26 @@ internal abstract class Computations : CurrentFrameInput, LastFrameState, Static

                        val delta = afterBreakpoint - beforeBreakpoint
                        val deltaIsFinite = delta.fastIsFinite()
                        if (!deltaIsFinite) {
                        if (deltaIsFinite && delta != 0f) {
                            // There is a discontinuity on this breakpoint, that needs to be
                            // animated. The delta is pushed to the spring, to consume the
                            // discontinuity over time.
                            springState =
                                springState.nudge(
                                    displacementDelta = -delta,
                                    velocityDelta = initialSpringVelocity,
                                )

                            // When *first* crossing a discontinuity in a given frame, the static
                            // mapped velocity observed during previous frame is added as initial
                            // velocity to the spring. This is done ot most once per frame, and only
                            // if there is an actual discontinuity.
                            initialSpringVelocity = 0f
                        } else {
                            // The before and / or after mapping produced an non-finite number,
                            // which is not allowed. This intentionally crashes eng-builds, since
                            // it's a bug in the Mapping implementation that must be fixed. On
                            // regular builds, it will likely cause a jumpcut.
                            Log.wtf(
                                TAG,
                                "Delta between breakpoints is undefined!\n" +
@@ -499,21 +525,6 @@ internal abstract class Computations : CurrentFrameInput, LastFrameState, Static
                            )
                        }

                        if (!hasJumped && delta != 0f) {
                            hasJumped = true
                            springState = springState.nudge(velocityDelta = directMappedVelocity)
                        }

                        springState =
                            springState.calculateUpdatedState(
                                nextBreakpointCrossTime - lastAnimationTime,
                                springParameters,
                            )
                        lastAnimationTime = nextBreakpointCrossTime

                        if (deltaIsFinite) {
                            springState = springState.nudge(displacementDelta = -delta)
                        }
                        segmentIndex += directionOffset
                        lastBreakpoint = nextBreakpoint
                        guaranteeState =
+39 −39
Original line number Diff line number Diff line
@@ -214,25 +214,25 @@
        65,
        60,
        55,
        46.603424,
        42.153717,
        36.203827,
        30.321402,
        25.1608,
        21.651463,
        18.9976,
        17.06427,
        15.6970415,
        14.754084,
        14.11806,
        13.697852,
        13.425745,
        13.253073,
        13.145809,
        13.080716,
        13.042264,
        13.020281,
        13.008238,
        50,
        43.38443,
        36.351646,
        29.990938,
        24.672552,
        21.162388,
        18.574236,
        16.725906,
        15.440355,
        14.566638,
        13.985239,
        13.6060915,
        13.363756,
        13.212058,
        13.11921,
        13.063812,
        13.031747,
        13.013887,
        13.004453,
        13,
        13.75,
        14.5,
@@ -245,26 +245,26 @@
        28.15,
        30.1,
        32.05,
        35.264374,
        44.949898,
        58.693554,
        67.97366,
        76.22729,
        82.931595,
        88.0746,
        91.862114,
        94.56434,
        96.44223,
        97.71758,
        98.56564,
        99.118324,
        99.47132,
        99.69214,
        99.82718,
        99.90767,
        99.954216,
        99.980095,
        99.99374,
        34,
        44.585567,
        58.759357,
        68.21262,
        76.507256,
        83.19111,
        88.2904,
        92.03026,
        94.689606,
        96.532425,
        97.780754,
        98.60885,
        99.14723,
        99.49028,
        99.70432,
        99.83485,
        99.9124,
        99.957054,
        99.98176,
        99.994675,
        100
      ]
    },
+24 −24
Original line number Diff line number Diff line
@@ -133,30 +133,30 @@
        65,
        60,
        55,
        46.603424,
        42.153717,
        36.203827,
        30.321402,
        25.1608,
        20.901463,
        17.4976,
        14.814271,
        12.6970415,
        6.739443,
        1.0775535,
        0.635472,
        0.35061052,
        0.17432979,
        0.07051067,
        0.013341078,
        -0.014990943,
        -0.02636234,
        -0.028412364,
        -0.025858387,
        -0.02147111,
        -0.016770272,
        -0.012503948,
        -0.008967604,
        50,
        43.38443,
        36.351646,
        29.990938,
        24.672552,
        20.412388,
        17.074236,
        14.475905,
        12.440355,
        6.552413,
        0.9461464,
        0.54626375,
        0.29212147,
        0.13740596,
        0.048214816,
        0.0006277391,
        -0.021660766,
        -0.02938723,
        -0.029362231,
        -0.02572238,
        -0.020845085,
        -0.015992891,
        -0.01175198,
        -0.008320414,
        0
      ]
    },
Loading