Merge "Reformat unfold lib with ktfmt"

This commit is contained in:
Nicolò Mazzucato
2022-01-20 13:18:30 +00:00
committed by Android (Google) Code Review
19 changed files with 204 additions and 229 deletions

View File

@@ -16,12 +16,14 @@
package com.android.systemui.unfold
import android.annotation.FloatRange
import com.android.systemui.unfold.UnfoldTransitionProgressProvider.TransitionProgressListener
import com.android.systemui.statusbar.policy.CallbackController
import com.android.systemui.unfold.UnfoldTransitionProgressProvider.TransitionProgressListener
/**
* Interface that allows to receive unfold transition progress updates.
*
* It can be used to update view properties based on the current animation progress.
*
* onTransitionProgress callback could be called on each frame.
*
* Use [createUnfoldTransitionProgressProvider] to create instances of this interface

View File

@@ -18,9 +18,8 @@ package com.android.systemui.unfold.config
import android.content.Context
import android.os.SystemProperties
internal class ResourceUnfoldTransitionConfig(
private val context: Context
) : UnfoldTransitionConfig {
internal class ResourceUnfoldTransitionConfig(private val context: Context) :
UnfoldTransitionConfig {
override val isEnabled: Boolean
get() = readIsEnabledResource() && isPropertyEnabled
@@ -29,19 +28,22 @@ internal class ResourceUnfoldTransitionConfig(
get() = readIsHingeAngleEnabled()
private val isPropertyEnabled: Boolean
get() = SystemProperties.getInt(UNFOLD_TRANSITION_MODE_PROPERTY_NAME,
UNFOLD_TRANSITION_PROPERTY_ENABLED) == UNFOLD_TRANSITION_PROPERTY_ENABLED
get() =
SystemProperties.getInt(
UNFOLD_TRANSITION_MODE_PROPERTY_NAME, UNFOLD_TRANSITION_PROPERTY_ENABLED) ==
UNFOLD_TRANSITION_PROPERTY_ENABLED
private fun readIsEnabledResource(): Boolean = context.resources
.getBoolean(com.android.internal.R.bool.config_unfoldTransitionEnabled)
private fun readIsEnabledResource(): Boolean =
context.resources.getBoolean(com.android.internal.R.bool.config_unfoldTransitionEnabled)
private fun readIsHingeAngleEnabled(): Boolean = context.resources
.getBoolean(com.android.internal.R.bool.config_unfoldTransitionHingeAngle)
private fun readIsHingeAngleEnabled(): Boolean =
context.resources.getBoolean(com.android.internal.R.bool.config_unfoldTransitionHingeAngle)
}
/**
* Temporary persistent property to control unfold transition mode
* See [com.android.unfold.config.AnimationMode]
* 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_enabled"
private const val UNFOLD_TRANSITION_PROPERTY_ENABLED = 1

View File

@@ -25,21 +25,17 @@ import com.android.systemui.unfold.updates.FOLD_UPDATE_UNFOLDED_SCREEN_AVAILABLE
import com.android.systemui.unfold.updates.FoldStateProvider
import com.android.systemui.unfold.updates.FoldStateProvider.FoldUpdate
/**
* Emits animation progress with fixed timing after unfolding
*/
/** Emits animation progress with fixed timing after unfolding */
internal class FixedTimingTransitionProgressProvider(
private val foldStateProvider: FoldStateProvider
) : UnfoldTransitionProgressProvider, FoldStateProvider.FoldUpdatesListener {
private val animatorListener = AnimatorListener()
private val animator =
ObjectAnimator.ofFloat(this, AnimationProgressProperty, 0f, 1f)
.apply {
duration = TRANSITION_TIME_MILLIS
addListener(animatorListener)
}
ObjectAnimator.ofFloat(this, AnimationProgressProperty, 0f, 1f).apply {
duration = TRANSITION_TIME_MILLIS
addListener(animatorListener)
}
private var transitionProgress: Float = 0.0f
set(value) {
@@ -62,10 +58,8 @@ internal class FixedTimingTransitionProgressProvider(
override fun onFoldUpdate(@FoldUpdate update: Int) {
when (update) {
FOLD_UPDATE_UNFOLDED_SCREEN_AVAILABLE ->
animator.start()
FOLD_UPDATE_FINISH_CLOSED ->
animator.cancel()
FOLD_UPDATE_UNFOLDED_SCREEN_AVAILABLE -> animator.start()
FOLD_UPDATE_FINISH_CLOSED -> animator.cancel()
}
}
@@ -77,16 +71,12 @@ internal class FixedTimingTransitionProgressProvider(
listeners.remove(listener)
}
override fun onHingeAngleUpdate(angle: Float) {
}
override fun onHingeAngleUpdate(angle: Float) {}
private object AnimationProgressProperty :
FloatProperty<FixedTimingTransitionProgressProvider>("animation_progress") {
override fun setValue(
provider: FixedTimingTransitionProgressProvider,
value: Float
) {
override fun setValue(provider: FixedTimingTransitionProgressProvider, value: Float) {
provider.transitionProgress = value
}
@@ -104,11 +94,9 @@ internal class FixedTimingTransitionProgressProvider(
listeners.forEach { it.onTransitionFinished() }
}
override fun onAnimationRepeat(animator: Animator) {
}
override fun onAnimationRepeat(animator: Animator) {}
override fun onAnimationCancel(animator: Animator) {
}
override fun onAnimationCancel(animator: Animator) {}
}
private companion object {

View File

@@ -23,10 +23,10 @@ import androidx.dynamicanimation.animation.SpringAnimation
import androidx.dynamicanimation.animation.SpringForce
import com.android.systemui.unfold.UnfoldTransitionProgressProvider
import com.android.systemui.unfold.UnfoldTransitionProgressProvider.TransitionProgressListener
import com.android.systemui.unfold.updates.FOLD_UPDATE_FINISH_HALF_OPEN
import com.android.systemui.unfold.updates.FOLD_UPDATE_FINISH_CLOSED
import com.android.systemui.unfold.updates.FOLD_UPDATE_START_CLOSING
import com.android.systemui.unfold.updates.FOLD_UPDATE_FINISH_FULL_OPEN
import com.android.systemui.unfold.updates.FOLD_UPDATE_FINISH_HALF_OPEN
import com.android.systemui.unfold.updates.FOLD_UPDATE_START_CLOSING
import com.android.systemui.unfold.updates.FOLD_UPDATE_UNFOLDED_SCREEN_AVAILABLE
import com.android.systemui.unfold.updates.FoldStateProvider
import com.android.systemui.unfold.updates.FoldStateProvider.FoldUpdate
@@ -35,13 +35,10 @@ import com.android.systemui.unfold.updates.FoldStateProvider.FoldUpdatesListener
/** Maps fold updates to unfold transition progress using DynamicAnimation. */
internal class PhysicsBasedUnfoldTransitionProgressProvider(
private val foldStateProvider: FoldStateProvider
) :
UnfoldTransitionProgressProvider,
FoldUpdatesListener,
DynamicAnimation.OnAnimationEndListener {
) : UnfoldTransitionProgressProvider, FoldUpdatesListener, DynamicAnimation.OnAnimationEndListener {
private val springAnimation = SpringAnimation(this, AnimationProgressProperty)
.apply {
private val springAnimation =
SpringAnimation(this, AnimationProgressProperty).apply {
addEndListener(this@PhysicsBasedUnfoldTransitionProgressProvider)
}
@@ -121,9 +118,7 @@ internal class PhysicsBasedUnfoldTransitionProgressProvider(
isTransitionRunning = false
springAnimation.cancel()
listeners.forEach {
it.onTransitionFinished()
}
listeners.forEach { it.onTransitionFinished() }
if (DEBUG) {
Log.d(TAG, "onTransitionFinished")
@@ -143,9 +138,7 @@ internal class PhysicsBasedUnfoldTransitionProgressProvider(
}
private fun onStartTransition() {
listeners.forEach {
it.onTransitionStarted()
}
listeners.forEach { it.onTransitionStarted() }
isTransitionRunning = true
if (DEBUG) {
@@ -157,11 +150,12 @@ internal class PhysicsBasedUnfoldTransitionProgressProvider(
if (!isTransitionRunning) onStartTransition()
springAnimation.apply {
spring = SpringForce().apply {
finalPosition = startValue
dampingRatio = SpringForce.DAMPING_RATIO_NO_BOUNCY
stiffness = SPRING_STIFFNESS
}
spring =
SpringForce().apply {
finalPosition = startValue
dampingRatio = SpringForce.DAMPING_RATIO_NO_BOUNCY
stiffness = SPRING_STIFFNESS
}
minimumVisibleChange = MINIMAL_VISIBLE_CHANGE
setStartValue(startValue)
setMinValue(0f)

View File

@@ -45,11 +45,9 @@ constructor(
private val outputListeners: MutableList<FoldUpdatesListener> = mutableListOf()
@FoldUpdate
private var lastFoldUpdate: Int? = null
@FoldUpdate private var lastFoldUpdate: Int? = null
@FloatRange(from = 0.0, to = 180.0)
private var lastHingeAngle: Float = 0f
@FloatRange(from = 0.0, to = 180.0) private var lastHingeAngle: Float = 0f
private val hingeAngleListener = HingeAngleListener()
private val screenListener = ScreenStatusListener()
@@ -60,10 +58,7 @@ constructor(
private var isUnfoldHandled = true
override fun start() {
deviceStateManager.registerCallback(
mainExecutor,
foldStateListener
)
deviceStateManager.registerCallback(mainExecutor, foldStateListener)
screenStatusProvider.addCallback(screenListener)
hingeAngleProvider.addCallback(hingeAngleListener)
}
@@ -87,11 +82,14 @@ constructor(
get() = !isFolded && lastFoldUpdate == FOLD_UPDATE_FINISH_FULL_OPEN
private val isTransitionInProgess: Boolean
get() = lastFoldUpdate == FOLD_UPDATE_START_OPENING ||
get() =
lastFoldUpdate == FOLD_UPDATE_START_OPENING ||
lastFoldUpdate == FOLD_UPDATE_START_CLOSING
private fun onHingeAngle(angle: Float) {
if (DEBUG) { Log.d(TAG, "Hinge angle: $angle, lastHingeAngle: $lastHingeAngle") }
if (DEBUG) {
Log.d(TAG, "Hinge angle: $angle, lastHingeAngle: $lastHingeAngle")
}
val isClosing = angle < lastHingeAngle
val isFullyOpened = FULLY_OPEN_DEGREES - angle < FULLY_OPEN_THRESHOLD_DEGREES
@@ -116,24 +114,28 @@ constructor(
}
private inner class FoldStateListener(context: Context) :
DeviceStateManager.FoldStateListener(context, { folded: Boolean ->
isFolded = folded
lastHingeAngle = FULLY_CLOSED_DEGREES
DeviceStateManager.FoldStateListener(
context,
{ folded: Boolean ->
isFolded = folded
lastHingeAngle = FULLY_CLOSED_DEGREES
if (folded) {
hingeAngleProvider.stop()
notifyFoldUpdate(FOLD_UPDATE_FINISH_CLOSED)
cancelTimeout()
isUnfoldHandled = false
} else {
notifyFoldUpdate(FOLD_UPDATE_START_OPENING)
rescheduleAbortAnimationTimeout()
hingeAngleProvider.start()
}
})
if (folded) {
hingeAngleProvider.stop()
notifyFoldUpdate(FOLD_UPDATE_FINISH_CLOSED)
cancelTimeout()
isUnfoldHandled = false
} else {
notifyFoldUpdate(FOLD_UPDATE_START_OPENING)
rescheduleAbortAnimationTimeout()
hingeAngleProvider.start()
}
})
private fun notifyFoldUpdate(@FoldUpdate update: Int) {
if (DEBUG) { Log.d(TAG, stateToString(update)) }
if (DEBUG) {
Log.d(TAG, stateToString(update))
}
outputListeners.forEach { it.onFoldUpdate(update) }
lastFoldUpdate = update
}
@@ -149,8 +151,7 @@ constructor(
handler.removeCallbacks(timeoutRunnable)
}
private inner class ScreenStatusListener :
ScreenStatusProvider.ScreenListener {
private inner class ScreenStatusListener : ScreenStatusProvider.ScreenListener {
override fun onScreenTurnedOn() {
// Trigger this event only if we are unfolded and this is the first screen
@@ -198,9 +199,7 @@ private const val DEBUG = false
* Time after which [FOLD_UPDATE_FINISH_HALF_OPEN] is emitted following a
* [FOLD_UPDATE_START_CLOSING] or [FOLD_UPDATE_START_OPENING] event, if an end state is not reached.
*/
@VisibleForTesting
const val HALF_OPENED_TIMEOUT_MILLIS = 1000L
@VisibleForTesting const val HALF_OPENED_TIMEOUT_MILLIS = 1000L
/** Threshold after which we consider the device fully unfolded. */
@VisibleForTesting
const val FULLY_OPEN_THRESHOLD_DEGREES = 15f
@VisibleForTesting const val FULLY_OPEN_THRESHOLD_DEGREES = 15f

View File

@@ -17,8 +17,8 @@ package com.android.systemui.unfold.updates
import android.annotation.FloatRange
import android.annotation.IntDef
import com.android.systemui.unfold.updates.FoldStateProvider.FoldUpdatesListener
import com.android.systemui.statusbar.policy.CallbackController
import com.android.systemui.unfold.updates.FoldStateProvider.FoldUpdatesListener
/**
* Allows to subscribe to main events related to fold/unfold process such as hinge angle update,
@@ -35,14 +35,16 @@ interface FoldStateProvider : CallbackController<FoldUpdatesListener> {
fun onFoldUpdate(@FoldUpdate update: Int)
}
@IntDef(prefix = ["FOLD_UPDATE_"], value = [
FOLD_UPDATE_START_OPENING,
FOLD_UPDATE_START_CLOSING,
FOLD_UPDATE_UNFOLDED_SCREEN_AVAILABLE,
FOLD_UPDATE_FINISH_HALF_OPEN,
FOLD_UPDATE_FINISH_FULL_OPEN,
FOLD_UPDATE_FINISH_CLOSED
])
@IntDef(
prefix = ["FOLD_UPDATE_"],
value =
[
FOLD_UPDATE_START_OPENING,
FOLD_UPDATE_START_CLOSING,
FOLD_UPDATE_UNFOLDED_SCREEN_AVAILABLE,
FOLD_UPDATE_FINISH_HALF_OPEN,
FOLD_UPDATE_FINISH_FULL_OPEN,
FOLD_UPDATE_FINISH_CLOSED])
@Retention(AnnotationRetention.SOURCE)
annotation class FoldUpdate
}

View File

@@ -3,15 +3,11 @@ package com.android.systemui.unfold.updates.hinge
import androidx.core.util.Consumer
internal object EmptyHingeAngleProvider : HingeAngleProvider {
override fun start() {
}
override fun start() {}
override fun stop() {
}
override fun stop() {}
override fun removeCallback(listener: Consumer<Float>) {
}
override fun removeCallback(listener: Consumer<Float>) {}
override fun addCallback(listener: Consumer<Float>) {
}
override fun addCallback(listener: Consumer<Float>) {}
}

View File

@@ -5,9 +5,10 @@ import com.android.systemui.statusbar.policy.CallbackController
/**
* Emits device hinge angle values (angle between two integral parts of the device).
* The hinge angle could be from 0 to 360 degrees inclusive.
* For foldable devices usually 0 corresponds to fully closed (folded) state and
* 180 degrees corresponds to fully open (flat) state
*
* The hinge angle could be from 0 to 360 degrees inclusive. For foldable devices usually 0
* corresponds to fully closed (folded) state and 180 degrees corresponds to fully open (flat)
* state.
*/
interface HingeAngleProvider : CallbackController<Consumer<Float>> {
fun start()

View File

@@ -6,9 +6,8 @@ import android.hardware.SensorEventListener
import android.hardware.SensorManager
import androidx.core.util.Consumer
internal class HingeSensorAngleProvider(
private val sensorManager: SensorManager
) : HingeAngleProvider {
internal class HingeSensorAngleProvider(private val sensorManager: SensorManager) :
HingeAngleProvider {
private val sensorListener = HingeAngleSensorListener()
private val listeners: MutableList<Consumer<Float>> = arrayListOf()
@@ -32,8 +31,7 @@ internal class HingeSensorAngleProvider(
private inner class HingeAngleSensorListener : SensorEventListener {
override fun onAccuracyChanged(sensor: Sensor?, accuracy: Int) {
}
override fun onAccuracyChanged(sensor: Sensor?, accuracy: Int) {}
override fun onSensorChanged(event: SensorEvent) {
listeners.forEach { it.accept(event.values[0]) }

View File

@@ -15,8 +15,8 @@
*/
package com.android.systemui.unfold.updates.screen
import com.android.systemui.unfold.updates.screen.ScreenStatusProvider.ScreenListener
import com.android.systemui.statusbar.policy.CallbackController
import com.android.systemui.unfold.updates.screen.ScreenStatusProvider.ScreenListener
interface ScreenStatusProvider : CallbackController<ScreenListener> {

View File

@@ -10,9 +10,8 @@ import com.android.systemui.unfold.UnfoldTransitionProgressProvider.TransitionPr
/**
* [UnfoldTransitionProgressProvider] that emits transition progress only when the display has
* default rotation or 180 degrees opposite rotation (ROTATION_0 or ROTATION_180).
* It could be helpful to run the animation only when the display's rotation is perpendicular
* to the fold.
* default rotation or 180 degrees opposite rotation (ROTATION_0 or ROTATION_180). It could be
* helpful to run the animation only when the display's rotation is perpendicular to the fold.
*/
class NaturalRotationUnfoldProgressProvider(
private val context: Context,
@@ -21,7 +20,7 @@ class NaturalRotationUnfoldProgressProvider(
) : UnfoldTransitionProgressProvider {
private val scopedUnfoldTransitionProgressProvider =
ScopedUnfoldTransitionProgressProvider(unfoldTransitionProgressProvider)
ScopedUnfoldTransitionProgressProvider(unfoldTransitionProgressProvider)
private val rotationWatcher = RotationWatcher()
private var isNaturalRotation: Boolean = false
@@ -37,8 +36,8 @@ class NaturalRotationUnfoldProgressProvider(
}
private fun onRotationChanged(rotation: Int) {
val isNewRotationNatural = rotation == Surface.ROTATION_0 ||
rotation == Surface.ROTATION_180
val isNewRotationNatural =
rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180
if (isNaturalRotation != isNewRotationNatural) {
isNaturalRotation = isNewRotationNatural

View File

@@ -21,17 +21,18 @@ constructor(
private val scopedUnfoldTransitionProgressProvider =
ScopedUnfoldTransitionProgressProvider(progressProviderToWrap)
private val animatorDurationScaleObserver = object : ContentObserver(null) {
override fun onChange(selfChange: Boolean) {
onAnimatorScaleChanged()
private val animatorDurationScaleObserver =
object : ContentObserver(null) {
override fun onChange(selfChange: Boolean) {
onAnimatorScaleChanged()
}
}
}
init {
contentResolver.registerContentObserver(
Settings.Global.getUriFor(Settings.Global.ANIMATOR_DURATION_SCALE),
/* notifyForDescendants= */ false,
animatorDurationScaleObserver)
Settings.Global.getUriFor(Settings.Global.ANIMATOR_DURATION_SCALE),
/* notifyForDescendants= */ false,
animatorDurationScaleObserver)
onAnimatorScaleChanged()
}

View File

@@ -20,16 +20,18 @@ import com.android.systemui.unfold.UnfoldTransitionProgressProvider.TransitionPr
/**
* Manages progress listeners that can have smaller lifespan than the unfold animation.
* Allows to limit getting transition updates to only when
* [ScopedUnfoldTransitionProgressProvider.setReadyToHandleTransition] is called
* with readyToHandleTransition = true
*
* If the transition has already started by the moment when the clients are ready to play
* the transition then it will report transition started callback and current animation progress.
* Allows to limit getting transition updates to only when
* [ScopedUnfoldTransitionProgressProvider.setReadyToHandleTransition] is called with
* readyToHandleTransition = true
*
* If the transition has already started by the moment when the clients are ready to play the
* transition then it will report transition started callback and current animation progress.
*/
class ScopedUnfoldTransitionProgressProvider @JvmOverloads constructor(
source: UnfoldTransitionProgressProvider? = null
) : UnfoldTransitionProgressProvider, TransitionProgressListener {
class ScopedUnfoldTransitionProgressProvider
@JvmOverloads
constructor(source: UnfoldTransitionProgressProvider? = null) :
UnfoldTransitionProgressProvider, TransitionProgressListener {
private var source: UnfoldTransitionProgressProvider? = null
@@ -43,8 +45,8 @@ class ScopedUnfoldTransitionProgressProvider @JvmOverloads constructor(
setSourceProvider(source)
}
/**
* Sets the source for the unfold transition progress updates,
* it replaces current provider if it is already set
* Sets the source for the unfold transition progress updates. Replaces current provider if it
* is already set
* @param provider transition provider that emits transition progress updates
*/
fun setSourceProvider(provider: UnfoldTransitionProgressProvider?) {
@@ -60,8 +62,10 @@ class ScopedUnfoldTransitionProgressProvider @JvmOverloads constructor(
/**
* Allows to notify this provide whether the listeners can play the transition or not.
* Call this method with readyToHandleTransition = true when all listeners
* are ready to consume the transition progress events.
*
* Call this method with readyToHandleTransition = true when all listeners are ready to consume
* the transition progress events.
*
* Call it with readyToHandleTransition = false when listeners can't process the events.
*/
fun setReadyToHandleTransition(isReadyToHandleTransition: Boolean) {

View File

@@ -30,17 +30,17 @@ import dagger.Lazy
import javax.inject.Inject
/**
* Controls folding to AOD animation: when AOD is enabled and foldable device is folded
* we play a special AOD animation on the outer screen
* Controls folding to AOD animation: when AOD is enabled and foldable device is folded we play a
* special AOD animation on the outer screen
*/
@SysUIUnfoldScope
class FoldAodAnimationController @Inject constructor(
class FoldAodAnimationController
@Inject
constructor(
private val keyguardViewMediatorLazy: Lazy<KeyguardViewMediator>,
private val wakefulnessLifecycle: WakefulnessLifecycle,
private val globalSettings: GlobalSettings
) : CallbackController<FoldAodAnimationStatus>,
ScreenOffAnimation,
WakefulnessLifecycle.Observer {
) : CallbackController<FoldAodAnimationStatus>, ScreenOffAnimation, WakefulnessLifecycle.Observer {
private var alwaysOnEnabled: Boolean = false
private var isScrimOpaque: Boolean = false
@@ -58,17 +58,13 @@ class FoldAodAnimationController @Inject constructor(
wakefulnessLifecycle.addObserver(this)
}
/**
* Returns true if we should run fold to AOD animation
*/
override fun shouldPlayAnimation(): Boolean =
shouldPlayAnimation
/** Returns true if we should run fold to AOD animation */
override fun shouldPlayAnimation(): Boolean = shouldPlayAnimation
override fun startAnimation(): Boolean =
if (alwaysOnEnabled &&
wakefulnessLifecycle.lastSleepReason == PowerManager.GO_TO_SLEEP_REASON_DEVICE_FOLD &&
globalSettings.getString(Settings.Global.ANIMATOR_DURATION_SCALE) != "0"
) {
globalSettings.getString(Settings.Global.ANIMATOR_DURATION_SCALE) != "0") {
shouldPlayAnimation = true
isAnimationPlaying = true
@@ -107,9 +103,7 @@ class FoldAodAnimationController @Inject constructor(
}
}
/**
* Called when keyguard scrim opaque changed
*/
/** Called when keyguard scrim opaque changed */
override fun onScrimOpaqueChanged(isOpaque: Boolean) {
isScrimOpaque = isOpaque
@@ -130,27 +124,19 @@ class FoldAodAnimationController @Inject constructor(
}
}
override fun isAnimationPlaying(): Boolean =
isAnimationPlaying
override fun isAnimationPlaying(): Boolean = isAnimationPlaying
override fun isKeyguardHideDelayed(): Boolean =
isAnimationPlaying()
override fun isKeyguardHideDelayed(): Boolean = isAnimationPlaying()
override fun shouldShowAodIconsWhenShade(): Boolean =
shouldPlayAnimation()
override fun shouldShowAodIconsWhenShade(): Boolean = shouldPlayAnimation()
override fun shouldAnimateAodIcons(): Boolean =
!shouldPlayAnimation()
override fun shouldAnimateAodIcons(): Boolean = !shouldPlayAnimation()
override fun shouldAnimateDozingChange(): Boolean =
!shouldPlayAnimation()
override fun shouldAnimateDozingChange(): Boolean = !shouldPlayAnimation()
override fun shouldAnimateClockChange(): Boolean =
!isAnimationPlaying()
override fun shouldAnimateClockChange(): Boolean = !isAnimationPlaying()
/**
* Called when AOD status is changed
*/
/** Called when AOD status is changed */
override fun onAlwaysOnChanged(alwaysOn: Boolean) {
alwaysOnEnabled = alwaysOn
}

View File

@@ -29,12 +29,16 @@ import javax.inject.Inject
* Logs performance metrics regarding time to turn the inner screen on.
*
* This class assumes that [onFoldEvent] is always called before [onScreenTurnedOn].
*
* This should be used from only one process.
*
* For now, the focus is on the time the inner display is visible, but in the future, it is easily
* possible to monitor the time to go from the inner screen to the outer.
*/
@SysUISingleton
class UnfoldLatencyTracker @Inject constructor(
class UnfoldLatencyTracker
@Inject
constructor(
private val latencyTracker: LatencyTracker,
private val deviceStateManager: DeviceStateManager,
@UiBackground private val uiBgExecutor: Executor,
@@ -45,8 +49,11 @@ class UnfoldLatencyTracker @Inject constructor(
private var folded: Boolean? = null
private val foldStateListener = FoldStateListener(context)
private val isFoldable: Boolean
get() = context.resources.getIntArray(
com.android.internal.R.array.config_foldedDeviceStates).isNotEmpty()
get() =
context
.resources
.getIntArray(com.android.internal.R.array.config_foldedDeviceStates)
.isNotEmpty()
/** Registers for relevant events only if the device is foldable. */
fun init() {

View File

@@ -20,8 +20,8 @@ import android.content.Context
import android.graphics.PixelFormat
import android.hardware.devicestate.DeviceStateManager
import android.hardware.devicestate.DeviceStateManager.FoldStateListener
import android.hardware.input.InputManager
import android.hardware.display.DisplayManager
import android.hardware.input.InputManager
import android.os.Handler
import android.os.Trace
import android.view.Choreographer
@@ -46,7 +46,9 @@ import java.util.function.Consumer
import javax.inject.Inject
@SysUIUnfoldScope
class UnfoldLightRevealOverlayAnimation @Inject constructor(
class UnfoldLightRevealOverlayAnimation
@Inject
constructor(
private val context: Context,
private val deviceStateManager: DeviceStateManager,
private val displayManager: DisplayManager,
@@ -75,12 +77,13 @@ class UnfoldLightRevealOverlayAnimation @Inject constructor(
deviceStateManager.registerCallback(executor, FoldListener())
unfoldTransitionProgressProvider.addCallback(transitionListener)
val containerBuilder = SurfaceControl.Builder(SurfaceSession())
.setContainerLayer()
.setName("unfold-overlay-container")
val containerBuilder =
SurfaceControl.Builder(SurfaceSession())
.setContainerLayer()
.setName("unfold-overlay-container")
displayAreaHelper.get().attachToRootDisplayArea(Display.DEFAULT_DISPLAY,
containerBuilder) { builder ->
displayAreaHelper.get().attachToRootDisplayArea(
Display.DEFAULT_DISPLAY, containerBuilder) { builder ->
executor.execute {
overlayContainer = builder.build()
@@ -89,13 +92,13 @@ class UnfoldLightRevealOverlayAnimation @Inject constructor(
.show(overlayContainer)
.apply()
wwm = WindowlessWindowManager(context.resources.configuration,
overlayContainer, null)
wwm =
WindowlessWindowManager(context.resources.configuration, overlayContainer, null)
}
}
displayManager.registerDisplayListener(displayListener, handler,
DisplayManager.EVENT_FLAG_DISPLAY_CHANGED)
displayManager.registerDisplayListener(
displayListener, handler, DisplayManager.EVENT_FLAG_DISPLAY_CHANGED)
// Get unfolded display size immediately as 'current display info' might be
// not up-to-date during unfolding
@@ -136,8 +139,8 @@ class UnfoldLightRevealOverlayAnimation @Inject constructor(
ensureOverlayRemoved()
val newRoot = SurfaceControlViewHost(context, context.display!!, wwm, false)
val newView = LightRevealScrim(context, null)
.apply {
val newView =
LightRevealScrim(context, null).apply {
revealEffect = createLightRevealEffect()
isScrimOpaqueChangedListener = Consumer {}
revealAmount = 0f
@@ -147,8 +150,7 @@ class UnfoldLightRevealOverlayAnimation @Inject constructor(
newRoot.setView(newView, params)
onOverlayReady?.let { callback ->
Trace.beginAsyncSection(
"UnfoldLightRevealOverlayAnimation#relayout", 0)
Trace.beginAsyncSection("UnfoldLightRevealOverlayAnimation#relayout", 0)
newRoot.relayout(params) { transaction ->
val vsyncId = Choreographer.getSfInstance().vsyncId
@@ -161,15 +163,11 @@ class UnfoldLightRevealOverlayAnimation @Inject constructor(
// (turn on the brightness) only when the content is actually visible as it
// might be presented only in the next frame.
// See b/197538198
transaction.setFrameTimelineVsync(vsyncId)
.apply(/* sync */true)
transaction.setFrameTimelineVsync(vsyncId).apply(/* sync */ true)
transaction
.setFrameTimelineVsync(vsyncId + 1)
.apply(/* sync */ true)
transaction.setFrameTimelineVsync(vsyncId + 1).apply(/* sync */ true)
Trace.endAsyncSection(
"UnfoldLightRevealOverlayAnimation#relayout", 0)
Trace.endAsyncSection("UnfoldLightRevealOverlayAnimation#relayout", 0)
callback.run()
}
}
@@ -185,10 +183,10 @@ class UnfoldLightRevealOverlayAnimation @Inject constructor(
val rotation = context.display!!.rotation
val isNatural = rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180
params.height = if (isNatural)
unfoldedDisplayInfo.naturalHeight else unfoldedDisplayInfo.naturalWidth
params.width = if (isNatural)
unfoldedDisplayInfo.naturalWidth else unfoldedDisplayInfo.naturalHeight
params.height =
if (isNatural) unfoldedDisplayInfo.naturalHeight else unfoldedDisplayInfo.naturalWidth
params.width =
if (isNatural) unfoldedDisplayInfo.naturalWidth else unfoldedDisplayInfo.naturalHeight
params.format = PixelFormat.TRANSLUCENT
params.type = WindowManager.LayoutParams.TYPE_DISPLAY_OVERLAY
@@ -206,8 +204,8 @@ class UnfoldLightRevealOverlayAnimation @Inject constructor(
}
private fun createLightRevealEffect(): LightRevealEffect {
val isVerticalFold = currentRotation == Surface.ROTATION_0 ||
currentRotation == Surface.ROTATION_180
val isVerticalFold =
currentRotation == Surface.ROTATION_0 || currentRotation == Surface.ROTATION_180
return LinearLightRevealEffect(isVertical = isVerticalFold)
}
@@ -218,7 +216,8 @@ class UnfoldLightRevealOverlayAnimation @Inject constructor(
}
private fun getUnfoldedDisplayInfo(): DisplayInfo =
displayManager.displays
displayManager
.displays
.asSequence()
.map { DisplayInfo().apply { it.getDisplayInfo(this) } }
.filter { it.type == Display.TYPE_INTERNAL }
@@ -255,18 +254,19 @@ class UnfoldLightRevealOverlayAnimation @Inject constructor(
}
}
override fun onDisplayAdded(displayId: Int) {
}
override fun onDisplayAdded(displayId: Int) {}
override fun onDisplayRemoved(displayId: Int) {
}
override fun onDisplayRemoved(displayId: Int) {}
}
private inner class FoldListener : FoldStateListener(context, Consumer { isFolded ->
if (isFolded) {
ensureOverlayRemoved()
isUnfoldHandled = false
}
this.isFolded = isFolded
})
private inner class FoldListener :
FoldStateListener(
context,
Consumer { isFolded ->
if (isFolded) {
ensureOverlayRemoved()
isUnfoldHandled = false
}
this.isFolded = isFolded
})
}

View File

@@ -21,29 +21,23 @@ import com.android.wm.shell.unfold.ShellUnfoldProgressProvider
import com.android.wm.shell.unfold.ShellUnfoldProgressProvider.UnfoldListener
import java.util.concurrent.Executor
class UnfoldProgressProvider(
private val unfoldProgressProvider: UnfoldTransitionProgressProvider
) : ShellUnfoldProgressProvider {
class UnfoldProgressProvider(private val unfoldProgressProvider: UnfoldTransitionProgressProvider) :
ShellUnfoldProgressProvider {
override fun addListener(executor: Executor, listener: UnfoldListener) {
unfoldProgressProvider.addCallback(object : TransitionProgressListener {
override fun onTransitionStarted() {
executor.execute {
listener.onStateChangeStarted()
unfoldProgressProvider.addCallback(
object : TransitionProgressListener {
override fun onTransitionStarted() {
executor.execute { listener.onStateChangeStarted() }
}
}
override fun onTransitionProgress(progress: Float) {
executor.execute {
listener.onStateChangeProgress(progress)
override fun onTransitionProgress(progress: Float) {
executor.execute { listener.onStateChangeProgress(progress) }
}
}
override fun onTransitionFinished() {
executor.execute {
listener.onStateChangeFinished()
override fun onTransitionFinished() {
executor.execute { listener.onStateChangeFinished() }
}
}
})
})
}
}

View File

@@ -90,7 +90,7 @@ class UnfoldTransitionModule {
config: UnfoldTransitionConfig,
provider: Optional<UnfoldTransitionProgressProvider>
): ShellUnfoldProgressProvider =
if (config.isEnabled && provider.isPresent()) {
if (config.isEnabled && provider.isPresent) {
UnfoldProgressProvider(provider.get())
} else {
ShellUnfoldProgressProvider.NO_PROVIDER

View File

@@ -21,7 +21,9 @@ import com.android.systemui.util.WallpaperController
import javax.inject.Inject
@SysUIUnfoldScope
class UnfoldTransitionWallpaperController @Inject constructor(
class UnfoldTransitionWallpaperController
@Inject
constructor(
private val unfoldTransitionProgressProvider: UnfoldTransitionProgressProvider,
private val wallpaperController: WallpaperController
) {