Use hinge angle sensor based unfold animation by default

Enables hinge angle driven unfold animation by default
on devices where hinge angle sensor is available,
uses fixed timing transition otherwise.

Bug: 195404647
Test: manual
Change-Id: I36e85a67664dcc579c18bfef870158e86aa921b9
This commit is contained in:
Nick Chameyev
2021-09-09 14:34:57 +01:00
parent 5c9e2243a0
commit a250b92ebc
4 changed files with 9 additions and 102 deletions

View File

@@ -22,7 +22,6 @@ import android.hardware.SensorManager
import android.hardware.devicestate.DeviceStateManager
import android.os.Handler
import com.android.systemui.unfold.updates.screen.ScreenStatusProvider
import com.android.systemui.unfold.config.ANIMATION_MODE_HINGE_ANGLE
import com.android.systemui.unfold.config.ResourceUnfoldTransitionConfig
import com.android.systemui.unfold.config.UnfoldTransitionConfig
import com.android.systemui.unfold.progress.FixedTimingTransitionProgressProvider
@@ -30,7 +29,6 @@ import com.android.systemui.unfold.progress.PhysicsBasedUnfoldTransitionProgress
import com.android.systemui.unfold.updates.DeviceFoldStateProvider
import com.android.systemui.unfold.updates.hinge.EmptyHingeAngleProvider
import com.android.systemui.unfold.updates.hinge.HingeSensorAngleProvider
import com.android.systemui.unfold.updates.hinge.RotationSensorHingeAngleProvider
import java.lang.IllegalStateException
import java.util.concurrent.Executor
@@ -50,14 +48,8 @@ fun createUnfoldTransitionProgressProvider(
}
val hingeAngleProvider =
if (config.mode == ANIMATION_MODE_HINGE_ANGLE) {
// TODO: after removing temporary "config.mode" we should just
// switch between fixed timing and hinge sensor based on this flag
if (config.isHingeAngleEnabled) {
HingeSensorAngleProvider(sensorManager)
} else {
RotationSensorHingeAngleProvider(sensorManager)
}
if (config.isHingeAngleEnabled) {
HingeSensorAngleProvider(sensorManager)
} else {
EmptyHingeAngleProvider()
}
@@ -70,7 +62,7 @@ fun createUnfoldTransitionProgressProvider(
mainExecutor
)
return if (config.mode == ANIMATION_MODE_HINGE_ANGLE) {
return if (config.isHingeAngleEnabled) {
PhysicsBasedUnfoldTransitionProgressProvider(
mainHandler,
foldStateProvider

View File

@@ -23,17 +23,16 @@ internal class ResourceUnfoldTransitionConfig(
) : UnfoldTransitionConfig {
override val isEnabled: Boolean
get() = readIsEnabled() && mode != ANIMATION_MODE_DISABLED
get() = readIsEnabledResource() && isPropertyEnabled
override val isHingeAngleEnabled: Boolean
get() = readIsHingeAngleEnabled()
@AnimationMode
override val mode: Int
private val isPropertyEnabled: Boolean
get() = SystemProperties.getInt(UNFOLD_TRANSITION_MODE_PROPERTY_NAME,
ANIMATION_MODE_FIXED_TIMING)
UNFOLD_TRANSITION_PROPERTY_ENABLED) == UNFOLD_TRANSITION_PROPERTY_ENABLED
private fun readIsEnabled(): Boolean = context.resources
private fun readIsEnabledResource(): Boolean = context.resources
.getBoolean(com.android.internal.R.bool.config_unfoldTransitionEnabled)
private fun readIsHingeAngleEnabled(): Boolean = context.resources
@@ -44,4 +43,5 @@ internal class ResourceUnfoldTransitionConfig(
* Temporary persistent property to control unfold transition mode
* See [com.android.unfold.config.AnimationMode]
*/
private const val UNFOLD_TRANSITION_MODE_PROPERTY_NAME = "persist.unfold.transition_mode"
private const val UNFOLD_TRANSITION_MODE_PROPERTY_NAME = "persist.unfold.transition_enabled"
private const val UNFOLD_TRANSITION_PROPERTY_ENABLED = 1

View File

@@ -15,25 +15,7 @@
*/
package com.android.systemui.unfold.config
import android.annotation.IntDef
interface UnfoldTransitionConfig {
val isEnabled: Boolean
val isHingeAngleEnabled: Boolean
@AnimationMode
val mode: Int
}
@IntDef(prefix = ["ANIMATION_MODE_"], value = [
ANIMATION_MODE_DISABLED,
ANIMATION_MODE_FIXED_TIMING,
ANIMATION_MODE_HINGE_ANGLE
])
@Retention(AnnotationRetention.SOURCE)
annotation class AnimationMode
const val ANIMATION_MODE_DISABLED = 0
const val ANIMATION_MODE_FIXED_TIMING = 1
const val ANIMATION_MODE_HINGE_ANGLE = 2

View File

@@ -1,67 +0,0 @@
package com.android.systemui.unfold.updates.hinge
import android.hardware.Sensor
import android.hardware.SensorEvent
import android.hardware.SensorEventListener
import android.hardware.SensorManager
import androidx.core.util.Consumer
import com.android.systemui.shared.recents.utilities.Utilities
/**
* Temporary hinge angle provider that uses rotation sensor instead.
* It requires to have the device in a certain position to work correctly
* (flat to the ground)
*/
internal class RotationSensorHingeAngleProvider(
private val sensorManager: SensorManager
) : HingeAngleProvider {
private val sensorListener = HingeAngleSensorListener()
private val listeners: MutableList<Consumer<Float>> = arrayListOf()
override fun start() {
val sensor = sensorManager.getDefaultSensor(Sensor.TYPE_GAME_ROTATION_VECTOR)
sensorManager.registerListener(sensorListener, sensor, SensorManager.SENSOR_DELAY_FASTEST)
}
override fun stop() {
sensorManager.unregisterListener(sensorListener)
}
override fun removeCallback(listener: Consumer<Float>) {
listeners.remove(listener)
}
override fun addCallback(listener: Consumer<Float>) {
listeners.add(listener)
}
private fun onHingeAngle(angle: Float) {
listeners.forEach { it.accept(angle) }
}
private inner class HingeAngleSensorListener : SensorEventListener {
override fun onAccuracyChanged(sensor: Sensor?, accuracy: Int) {
}
override fun onSensorChanged(event: SensorEvent) {
// Jumbojack sends incorrect sensor reading 1.0f event in the beginning, let's ignore it
if (event.values[3] == 1.0f) return
val angleRadians = event.values.convertToAngle()
val hingeAngleDegrees = Math.toDegrees(angleRadians).toFloat()
val angle = Utilities.clamp(hingeAngleDegrees, FULLY_CLOSED_DEGREES, FULLY_OPEN_DEGREES)
onHingeAngle(angle)
}
private val rotationMatrix = FloatArray(9)
private val resultOrientation = FloatArray(9)
private fun FloatArray.convertToAngle(): Double {
SensorManager.getRotationMatrixFromVector(rotationMatrix, this)
SensorManager.getOrientation(rotationMatrix, resultOrientation)
return resultOrientation[2] + Math.PI
}
}
}