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:
@@ -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()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
|
||||
@@ -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) :
|
||||
|
||||
Reference in New Issue
Block a user