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
This commit is contained in:
Nicolo' Mazzucato
2023-01-16 14:47:14 +00:00
parent 9758d71bd9
commit d184e5ffa1
3 changed files with 50 additions and 10 deletions

View File

@@ -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()
}
}
}

View File

@@ -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.
*

View File

@@ -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) :