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

Commit d184e5ff authored by Nicolo' Mazzucato's avatar Nicolo' Mazzucato
Browse files

Optimize DeviceFoldStateProvider#onHingeAngle

isClosingThresholdMet calculation turn out to cause some binder transaction to know if the current top task is home activity. As it is very rarely used, it is now moved to the last position of the AND chain.

Instead of querying ActivityManager each time, now a listener is registered for top task changes.

This removes many useless binder transactions (but adds a binder transaction when DeviceFoldStateProvider is initialized)

Test: DeviceFoldStateProviderTest
Bug: 265666399
Change-Id: I9b44d7409261882a3b72ad5d7f5eb44a2eb3c2b1
parent 9758d71b
Loading
Loading
Loading
Loading
+37 −7
Original line number Diff line number Diff line
@@ -15,21 +15,51 @@
package com.android.systemui.unfold.system

import android.app.ActivityManager
import android.app.ActivityManager.RunningTaskInfo
import android.app.WindowConfiguration
import android.os.Trace
import com.android.systemui.shared.system.TaskStackChangeListener
import com.android.systemui.shared.system.TaskStackChangeListeners
import com.android.systemui.unfold.util.CurrentActivityTypeProvider
import javax.inject.Inject
import javax.inject.Singleton

@Singleton
class ActivityManagerActivityTypeProvider @Inject constructor(
    private val activityManager: ActivityManager
) : CurrentActivityTypeProvider {
class ActivityManagerActivityTypeProvider
@Inject
constructor(private val activityManager: ActivityManager) : CurrentActivityTypeProvider {

    override val isHomeActivity: Boolean?
        get() {
            val activityType = activityManager.getRunningTasks(/* maxNum= */ 1)
                    ?.getOrNull(0)?.topActivityType ?: return null
        get() = _isHomeActivity

            return activityType == WindowConfiguration.ACTIVITY_TYPE_HOME
    private var _isHomeActivity: Boolean? = null


    override fun init() {
        _isHomeActivity = activityManager.isOnHomeActivity()
        TaskStackChangeListeners.getInstance().registerTaskStackListener(taskStackChangeListener)
    }

    override fun uninit() {
        TaskStackChangeListeners.getInstance().unregisterTaskStackListener(taskStackChangeListener)
    }

    private val taskStackChangeListener =
        object : TaskStackChangeListener {
            override fun onTaskMovedToFront(taskInfo: RunningTaskInfo) {
                _isHomeActivity = taskInfo.isHomeActivity()
            }
        }

    private fun RunningTaskInfo.isHomeActivity(): Boolean =
        topActivityType == WindowConfiguration.ACTIVITY_TYPE_HOME

    private fun ActivityManager.isOnHomeActivity(): Boolean? {
        try {
            Trace.beginSection("isOnHomeActivity")
            return getRunningTasks(/* maxNum= */ 1)?.firstOrNull()?.isHomeActivity()
        } finally {
            Trace.endSection()
        }
    }
}
+8 −3
Original line number Diff line number Diff line
@@ -79,6 +79,7 @@ constructor(
        screenStatusProvider.addCallback(screenListener)
        hingeAngleProvider.addCallback(hingeAngleListener)
        rotationChangeProvider.addCallback(rotationListener)
        activityTypeProvider.init()
    }

    override fun stop() {
@@ -87,6 +88,7 @@ constructor(
        hingeAngleProvider.removeCallback(hingeAngleListener)
        hingeAngleProvider.stop()
        rotationChangeProvider.removeCallback(rotationListener)
        activityTypeProvider.uninit()
    }

    override fun addCallback(listener: FoldUpdatesListener) {
@@ -115,19 +117,17 @@ constructor(
        }

        val isClosing = angle < lastHingeAngle
        val closingThreshold = getClosingThreshold()
        val closingThresholdMet = closingThreshold == null || angle < closingThreshold
        val isFullyOpened = FULLY_OPEN_DEGREES - angle < FULLY_OPEN_THRESHOLD_DEGREES
        val closingEventDispatched = lastFoldUpdate == FOLD_UPDATE_START_CLOSING
        val screenAvailableEventSent = isUnfoldHandled

        if (isClosing // hinge angle should be decreasing since last update
                && closingThresholdMet // hinge angle is below certain threshold
                && !closingEventDispatched  // we haven't sent closing event already
                && !isFullyOpened // do not send closing event if we are in fully opened hinge
                                  // angle range as closing threshold could overlap this range
                && screenAvailableEventSent // do not send closing event if we are still in
                                            // the process of turning on the inner display
                && isClosingThresholdMet(angle) // hinge angle is below certain threshold.
        ) {
            notifyFoldUpdate(FOLD_UPDATE_START_CLOSING)
        }
@@ -146,6 +146,11 @@ constructor(
        outputListeners.forEach { it.onHingeAngleUpdate(angle) }
    }

    private fun isClosingThresholdMet(currentAngle: Float) : Boolean {
        val closingThreshold = getClosingThreshold()
        return closingThreshold == null || currentAngle < closingThreshold
    }

    /**
     * Fold animation should be started only after the threshold returned here.
     *
+5 −0
Original line number Diff line number Diff line
@@ -16,6 +16,11 @@ package com.android.systemui.unfold.util

interface CurrentActivityTypeProvider {
    val isHomeActivity: Boolean?

    /** Starts listening for task updates. */
    fun init() {}
    /** Stop listening for task updates. */
    fun uninit() {}
}

class EmptyCurrentActivityTypeProvider(override val isHomeActivity: Boolean? = null) :