Extract unfold classes to a separate library

No behaviour changes in this CL.
Extracted classes related to the fold/unfold
animation (that plays on foldable devices) to
a separate library that does not depend on
system classes. This is necessary to ease
reusing these classes in live wallpapers.

Bug: 231936088
Test: fold/unfold device
Change-Id: Ic1e1ec742867fca9c1209b930accd5738de18e39
diff --git a/packages/SystemUI/shared/Android.bp b/packages/SystemUI/shared/Android.bp
index 3cf5bc1..9f790c6 100644
--- a/packages/SystemUI/shared/Android.bp
+++ b/packages/SystemUI/shared/Android.bp
@@ -47,6 +47,7 @@
     ],
     static_libs: [
         "PluginCoreLib",
+        "SystemUIUnfoldLib",
         "androidx.dynamicanimation_dynamicanimation",
         "androidx.concurrent_concurrent-futures",
         "dagger2",
diff --git a/packages/SystemUI/shared/src/com/android/systemui/unfold/UnfoldSharedComponent.kt b/packages/SystemUI/shared/src/com/android/systemui/unfold/UnfoldSharedComponent.kt
deleted file mode 100644
index 9e5aeb8..0000000
--- a/packages/SystemUI/shared/src/com/android/systemui/unfold/UnfoldSharedComponent.kt
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.unfold
-
-import android.app.ActivityManager
-import android.content.ContentResolver
-import android.content.Context
-import android.hardware.SensorManager
-import android.hardware.devicestate.DeviceStateManager
-import android.os.Handler
-import com.android.systemui.dagger.qualifiers.Main
-import com.android.systemui.dagger.qualifiers.UiBackground
-import com.android.systemui.unfold.config.UnfoldTransitionConfig
-import com.android.systemui.unfold.updates.screen.ScreenStatusProvider
-import com.android.systemui.unfold.util.UnfoldTransitionATracePrefix
-import dagger.BindsInstance
-import dagger.Component
-import java.util.Optional
-import java.util.concurrent.Executor
-import javax.inject.Singleton
-
-/**
- * Provides [UnfoldTransitionProgressProvider]. The [Optional] is empty when the transition
- * animation is disabled.
- *
- * This component is meant to be used for places that don't use dagger. By providing those
- * parameters to the factory, all dagger objects are correctly instantiated. See
- * [createUnfoldTransitionProgressProvider] for an example.
- */
-@Singleton
-@Component(modules = [UnfoldSharedModule::class])
-internal interface UnfoldSharedComponent {
-
-    @Component.Factory
-    interface Factory {
-        fun create(
-            @BindsInstance context: Context,
-            @BindsInstance config: UnfoldTransitionConfig,
-            @BindsInstance screenStatusProvider: ScreenStatusProvider,
-            @BindsInstance deviceStateManager: DeviceStateManager,
-            @BindsInstance activityManager: ActivityManager,
-            @BindsInstance sensorManager: SensorManager,
-            @BindsInstance @Main handler: Handler,
-            @BindsInstance @Main executor: Executor,
-            @BindsInstance @UiBackground backgroundExecutor: Executor,
-            @BindsInstance @UnfoldTransitionATracePrefix tracingTagPrefix: String,
-            @BindsInstance contentResolver: ContentResolver = context.contentResolver
-        ): UnfoldSharedComponent
-    }
-
-    val unfoldTransitionProvider: Optional<UnfoldTransitionProgressProvider>
-}
diff --git a/packages/SystemUI/shared/src/com/android/systemui/unfold/UnfoldSharedModule.kt b/packages/SystemUI/shared/src/com/android/systemui/unfold/UnfoldSharedModule.kt
deleted file mode 100644
index c612995..0000000
--- a/packages/SystemUI/shared/src/com/android/systemui/unfold/UnfoldSharedModule.kt
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.unfold
-
-import android.hardware.SensorManager
-import com.android.systemui.dagger.qualifiers.UiBackground
-import com.android.systemui.unfold.config.UnfoldTransitionConfig
-import com.android.systemui.unfold.progress.FixedTimingTransitionProgressProvider
-import com.android.systemui.unfold.progress.PhysicsBasedUnfoldTransitionProgressProvider
-import com.android.systemui.unfold.updates.DeviceFoldStateProvider
-import com.android.systemui.unfold.updates.FoldStateProvider
-import com.android.systemui.unfold.updates.hinge.EmptyHingeAngleProvider
-import com.android.systemui.unfold.updates.hinge.HingeAngleProvider
-import com.android.systemui.unfold.updates.hinge.HingeSensorAngleProvider
-import com.android.systemui.unfold.util.ATraceLoggerTransitionProgressListener
-import com.android.systemui.unfold.util.ScaleAwareTransitionProgressProvider
-import dagger.Module
-import dagger.Provides
-import java.util.Optional
-import java.util.concurrent.Executor
-import javax.inject.Singleton
-
-@Module
-class UnfoldSharedModule {
-    @Provides
-    @Singleton
-    fun unfoldTransitionProgressProvider(
-        config: UnfoldTransitionConfig,
-        scaleAwareProviderFactory: ScaleAwareTransitionProgressProvider.Factory,
-        tracingListener: ATraceLoggerTransitionProgressListener,
-        foldStateProvider: FoldStateProvider
-    ): Optional<UnfoldTransitionProgressProvider> =
-        if (!config.isEnabled) {
-            Optional.empty()
-        } else {
-            val baseProgressProvider =
-                if (config.isHingeAngleEnabled) {
-                    PhysicsBasedUnfoldTransitionProgressProvider(foldStateProvider)
-                } else {
-                    FixedTimingTransitionProgressProvider(foldStateProvider)
-                }
-            Optional.of(
-                scaleAwareProviderFactory.wrap(baseProgressProvider).apply {
-                    // Always present callback that logs animation beginning and end.
-                    addCallback(tracingListener)
-                })
-        }
-
-    @Provides
-    @Singleton
-    fun provideFoldStateProvider(
-        deviceFoldStateProvider: DeviceFoldStateProvider
-    ): FoldStateProvider = deviceFoldStateProvider
-
-    @Provides
-    fun hingeAngleProvider(
-        config: UnfoldTransitionConfig,
-        sensorManager: SensorManager,
-        @UiBackground executor: Executor
-    ): HingeAngleProvider =
-        if (config.isHingeAngleEnabled) {
-            HingeSensorAngleProvider(sensorManager, executor)
-        } else {
-            EmptyHingeAngleProvider
-        }
-}
diff --git a/packages/SystemUI/shared/src/com/android/systemui/unfold/UnfoldTransitionFactory.kt b/packages/SystemUI/shared/src/com/android/systemui/unfold/UnfoldTransitionFactory.kt
deleted file mode 100644
index cc56007c..0000000
--- a/packages/SystemUI/shared/src/com/android/systemui/unfold/UnfoldTransitionFactory.kt
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-@file:JvmName("UnfoldTransitionFactory")
-
-package com.android.systemui.unfold
-
-import android.app.ActivityManager
-import android.content.Context
-import android.hardware.SensorManager
-import android.hardware.devicestate.DeviceStateManager
-import android.os.Handler
-import com.android.systemui.unfold.config.ResourceUnfoldTransitionConfig
-import com.android.systemui.unfold.config.UnfoldTransitionConfig
-import com.android.systemui.unfold.updates.screen.ScreenStatusProvider
-import java.util.concurrent.Executor
-
-/**
- * Factory for [UnfoldTransitionProgressProvider].
- *
- * This is needed as Launcher has to create the object manually. If dagger is available, this object
- * is provided in [UnfoldSharedModule].
- *
- * This should **never** be called from sysui, as the object is already provided in that process.
- */
-fun createUnfoldTransitionProgressProvider(
-    context: Context,
-    config: UnfoldTransitionConfig,
-    screenStatusProvider: ScreenStatusProvider,
-    deviceStateManager: DeviceStateManager,
-    activityManager: ActivityManager,
-    sensorManager: SensorManager,
-    mainHandler: Handler,
-    mainExecutor: Executor,
-    backgroundExecutor: Executor,
-    tracingTagPrefix: String
-): UnfoldTransitionProgressProvider =
-    DaggerUnfoldSharedComponent.factory()
-        .create(
-            context,
-            config,
-            screenStatusProvider,
-            deviceStateManager,
-            activityManager,
-            sensorManager,
-            mainHandler,
-            mainExecutor,
-            backgroundExecutor,
-            tracingTagPrefix)
-        .unfoldTransitionProvider
-        .orElse(null)
-        ?: throw IllegalStateException(
-            "Trying to create " +
-                "UnfoldTransitionProgressProvider when the transition is disabled")
-
-fun createConfig(context: Context): UnfoldTransitionConfig = ResourceUnfoldTransitionConfig(context)
diff --git a/packages/SystemUI/shared/src/com/android/systemui/unfold/UnfoldTransitionProgressProvider.kt b/packages/SystemUI/shared/src/com/android/systemui/unfold/UnfoldTransitionProgressProvider.kt
deleted file mode 100644
index 409dc95..0000000
--- a/packages/SystemUI/shared/src/com/android/systemui/unfold/UnfoldTransitionProgressProvider.kt
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.systemui.unfold
-
-import android.annotation.FloatRange
-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
- */
-interface UnfoldTransitionProgressProvider : CallbackController<TransitionProgressListener> {
-
-    fun destroy()
-
-    interface TransitionProgressListener {
-        fun onTransitionStarted() {}
-        fun onTransitionFinished() {}
-        fun onTransitionProgress(@FloatRange(from = 0.0, to = 1.0) progress: Float) {}
-    }
-}
diff --git a/packages/SystemUI/shared/src/com/android/systemui/unfold/config/ResourceUnfoldTransitionConfig.kt b/packages/SystemUI/shared/src/com/android/systemui/unfold/config/ResourceUnfoldTransitionConfig.kt
deleted file mode 100644
index d1b0639..0000000
--- a/packages/SystemUI/shared/src/com/android/systemui/unfold/config/ResourceUnfoldTransitionConfig.kt
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.systemui.unfold.config
-
-import android.content.Context
-import android.os.SystemProperties
-
-internal class ResourceUnfoldTransitionConfig(private val context: Context) :
-    UnfoldTransitionConfig {
-
-    override val isEnabled: Boolean
-        get() = readIsEnabledResource() && isPropertyEnabled
-
-    override val isHingeAngleEnabled: Boolean
-        get() = readIsHingeAngleEnabled()
-
-    private val isPropertyEnabled: Boolean
-        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 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].
- */
-private const val UNFOLD_TRANSITION_MODE_PROPERTY_NAME = "persist.unfold.transition_enabled"
-private const val UNFOLD_TRANSITION_PROPERTY_ENABLED = 1
diff --git a/packages/SystemUI/shared/src/com/android/systemui/unfold/config/UnfoldTransitionConfig.kt b/packages/SystemUI/shared/src/com/android/systemui/unfold/config/UnfoldTransitionConfig.kt
deleted file mode 100644
index 5b187b3..0000000
--- a/packages/SystemUI/shared/src/com/android/systemui/unfold/config/UnfoldTransitionConfig.kt
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.systemui.unfold.config
-
-interface UnfoldTransitionConfig {
-    val isEnabled: Boolean
-    val isHingeAngleEnabled: Boolean
-}
diff --git a/packages/SystemUI/shared/src/com/android/systemui/unfold/progress/FixedTimingTransitionProgressProvider.kt b/packages/SystemUI/shared/src/com/android/systemui/unfold/progress/FixedTimingTransitionProgressProvider.kt
deleted file mode 100644
index 4c85b05..0000000
--- a/packages/SystemUI/shared/src/com/android/systemui/unfold/progress/FixedTimingTransitionProgressProvider.kt
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.systemui.unfold.progress
-
-import android.animation.Animator
-import android.animation.ObjectAnimator
-import android.util.FloatProperty
-import com.android.systemui.unfold.UnfoldTransitionProgressProvider
-import com.android.systemui.unfold.UnfoldTransitionProgressProvider.TransitionProgressListener
-import com.android.systemui.unfold.updates.FOLD_UPDATE_FINISH_CLOSED
-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 */
-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)
-        }
-
-    private var transitionProgress: Float = 0.0f
-        set(value) {
-            listeners.forEach { it.onTransitionProgress(value) }
-            field = value
-        }
-
-    private val listeners: MutableList<TransitionProgressListener> = mutableListOf()
-
-    init {
-        foldStateProvider.addCallback(this)
-        foldStateProvider.start()
-    }
-
-    override fun destroy() {
-        animator.cancel()
-        foldStateProvider.removeCallback(this)
-        foldStateProvider.stop()
-    }
-
-    override fun onFoldUpdate(@FoldUpdate update: Int) {
-        when (update) {
-            FOLD_UPDATE_UNFOLDED_SCREEN_AVAILABLE -> animator.start()
-            FOLD_UPDATE_FINISH_CLOSED -> animator.cancel()
-        }
-    }
-
-    override fun addCallback(listener: TransitionProgressListener) {
-        listeners.add(listener)
-    }
-
-    override fun removeCallback(listener: TransitionProgressListener) {
-        listeners.remove(listener)
-    }
-
-    override fun onHingeAngleUpdate(angle: Float) {}
-
-    private object AnimationProgressProperty :
-        FloatProperty<FixedTimingTransitionProgressProvider>("animation_progress") {
-
-        override fun setValue(provider: FixedTimingTransitionProgressProvider, value: Float) {
-            provider.transitionProgress = value
-        }
-
-        override fun get(provider: FixedTimingTransitionProgressProvider): Float =
-            provider.transitionProgress
-    }
-
-    private inner class AnimatorListener : Animator.AnimatorListener {
-
-        override fun onAnimationStart(animator: Animator) {
-            listeners.forEach { it.onTransitionStarted() }
-        }
-
-        override fun onAnimationEnd(animator: Animator) {
-            listeners.forEach { it.onTransitionFinished() }
-        }
-
-        override fun onAnimationRepeat(animator: Animator) {}
-
-        override fun onAnimationCancel(animator: Animator) {}
-    }
-
-    private companion object {
-        private const val TRANSITION_TIME_MILLIS = 400L
-    }
-}
diff --git a/packages/SystemUI/shared/src/com/android/systemui/unfold/progress/PhysicsBasedUnfoldTransitionProgressProvider.kt b/packages/SystemUI/shared/src/com/android/systemui/unfold/progress/PhysicsBasedUnfoldTransitionProgressProvider.kt
deleted file mode 100644
index 04d920c..0000000
--- a/packages/SystemUI/shared/src/com/android/systemui/unfold/progress/PhysicsBasedUnfoldTransitionProgressProvider.kt
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.systemui.unfold.progress
-
-import android.util.Log
-import android.util.MathUtils.saturate
-import androidx.dynamicanimation.animation.DynamicAnimation
-import androidx.dynamicanimation.animation.FloatPropertyCompat
-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_CLOSED
-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
-import com.android.systemui.unfold.updates.FoldStateProvider.FoldUpdatesListener
-
-/** Maps fold updates to unfold transition progress using DynamicAnimation. */
-class PhysicsBasedUnfoldTransitionProgressProvider(
-    private val foldStateProvider: FoldStateProvider
-) : UnfoldTransitionProgressProvider, FoldUpdatesListener, DynamicAnimation.OnAnimationEndListener {
-
-    private val springAnimation =
-        SpringAnimation(this, AnimationProgressProperty).apply {
-            addEndListener(this@PhysicsBasedUnfoldTransitionProgressProvider)
-        }
-
-    private var isTransitionRunning = false
-    private var isAnimatedCancelRunning = false
-
-    private var transitionProgress: Float = 0.0f
-        set(value) {
-            if (isTransitionRunning) {
-                listeners.forEach { it.onTransitionProgress(value) }
-            }
-            field = value
-        }
-
-    private val listeners: MutableList<TransitionProgressListener> = mutableListOf()
-
-    init {
-        foldStateProvider.addCallback(this)
-        foldStateProvider.start()
-    }
-
-    override fun destroy() {
-        foldStateProvider.stop()
-    }
-
-    override fun onHingeAngleUpdate(angle: Float) {
-        if (!isTransitionRunning || isAnimatedCancelRunning) return
-        val progress = saturate(angle / FINAL_HINGE_ANGLE_POSITION)
-        springAnimation.animateToFinalPosition(progress)
-    }
-
-    override fun onFoldUpdate(@FoldUpdate update: Int) {
-        when (update) {
-            FOLD_UPDATE_UNFOLDED_SCREEN_AVAILABLE -> {
-                startTransition(startValue = 0f)
-
-                // Stop the animation if the device has already opened by the time when
-                // the display is available as we won't receive the full open event anymore
-                if (foldStateProvider.isFinishedOpening) {
-                    cancelTransition(endValue = 1f, animate = true)
-                }
-            }
-            FOLD_UPDATE_FINISH_FULL_OPEN, FOLD_UPDATE_FINISH_HALF_OPEN -> {
-                // Do not cancel if we haven't started the transition yet.
-                // This could happen when we fully unfolded the device before the screen
-                // became available. In this case we start and immediately cancel the animation
-                // in FOLD_UPDATE_UNFOLDED_SCREEN_AVAILABLE event handler, so we don't need to
-                // cancel it here.
-                if (isTransitionRunning) {
-                    cancelTransition(endValue = 1f, animate = true)
-                }
-            }
-            FOLD_UPDATE_FINISH_CLOSED -> {
-                cancelTransition(endValue = 0f, animate = false)
-            }
-            FOLD_UPDATE_START_CLOSING -> {
-                // The transition might be already running as the device might start closing several
-                // times before reaching an end state.
-                if (isTransitionRunning) {
-                    // If we are cancelling the animation, reset that so we can resume it normally.
-                    // The animation could be 'cancelled' when the user stops folding/unfolding
-                    // for some period of time or fully unfolds the device. In this case,
-                    // it is forced to run to the end ignoring all further hinge angle events.
-                    // By resetting this flag we allow reacting to hinge angle events again, so
-                    // the transition continues running.
-                    if (isAnimatedCancelRunning) {
-                        isAnimatedCancelRunning = false
-                    }
-                } else {
-                    startTransition(startValue = 1f)
-                }
-            }
-        }
-
-        if (DEBUG) {
-            Log.d(TAG, "onFoldUpdate = $update")
-        }
-    }
-
-    private fun cancelTransition(endValue: Float, animate: Boolean) {
-        if (isTransitionRunning && animate) {
-            isAnimatedCancelRunning = true
-            springAnimation.animateToFinalPosition(endValue)
-        } else {
-            transitionProgress = endValue
-            isAnimatedCancelRunning = false
-            isTransitionRunning = false
-            springAnimation.cancel()
-
-            listeners.forEach { it.onTransitionFinished() }
-
-            if (DEBUG) {
-                Log.d(TAG, "onTransitionFinished")
-            }
-        }
-    }
-
-    override fun onAnimationEnd(
-        animation: DynamicAnimation<out DynamicAnimation<*>>,
-        canceled: Boolean,
-        value: Float,
-        velocity: Float
-    ) {
-        if (isAnimatedCancelRunning) {
-            cancelTransition(value, animate = false)
-        }
-    }
-
-    private fun onStartTransition() {
-        listeners.forEach { it.onTransitionStarted() }
-        isTransitionRunning = true
-
-        if (DEBUG) {
-            Log.d(TAG, "onTransitionStarted")
-        }
-    }
-
-    private fun startTransition(startValue: Float) {
-        if (!isTransitionRunning) onStartTransition()
-
-        springAnimation.apply {
-            spring =
-                SpringForce().apply {
-                    finalPosition = startValue
-                    dampingRatio = SpringForce.DAMPING_RATIO_NO_BOUNCY
-                    stiffness = SPRING_STIFFNESS
-                }
-            minimumVisibleChange = MINIMAL_VISIBLE_CHANGE
-            setStartValue(startValue)
-            setMinValue(0f)
-            setMaxValue(1f)
-        }
-
-        springAnimation.start()
-    }
-
-    override fun addCallback(listener: TransitionProgressListener) {
-        listeners.add(listener)
-    }
-
-    override fun removeCallback(listener: TransitionProgressListener) {
-        listeners.remove(listener)
-    }
-
-    private object AnimationProgressProperty :
-        FloatPropertyCompat<PhysicsBasedUnfoldTransitionProgressProvider>("animation_progress") {
-
-        override fun setValue(
-            provider: PhysicsBasedUnfoldTransitionProgressProvider,
-            value: Float
-        ) {
-            provider.transitionProgress = value
-        }
-
-        override fun getValue(provider: PhysicsBasedUnfoldTransitionProgressProvider): Float =
-            provider.transitionProgress
-    }
-}
-
-private const val TAG = "PhysicsBasedUnfoldTransitionProgressProvider"
-private const val DEBUG = true
-
-private const val SPRING_STIFFNESS = 200.0f
-private const val MINIMAL_VISIBLE_CHANGE = 0.001f
-private const val FINAL_HINGE_ANGLE_POSITION = 165f
diff --git a/packages/SystemUI/shared/src/com/android/systemui/unfold/system/ActivityManagerActivityTypeProvider.kt b/packages/SystemUI/shared/src/com/android/systemui/unfold/system/ActivityManagerActivityTypeProvider.kt
new file mode 100644
index 0000000..7f2933e
--- /dev/null
+++ b/packages/SystemUI/shared/src/com/android/systemui/unfold/system/ActivityManagerActivityTypeProvider.kt
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+package com.android.systemui.unfold.system
+
+import android.app.ActivityManager
+import android.app.WindowConfiguration
+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 {
+
+    override val isHomeActivity: Boolean?
+        get() {
+            val activityType = activityManager.getRunningTasks(/* maxNum= */ 1)
+                    ?.getOrNull(0)?.topActivityType ?: return null
+
+            return activityType == WindowConfiguration.ACTIVITY_TYPE_HOME
+        }
+}
diff --git a/packages/SystemUI/shared/src/com/android/systemui/unfold/system/DeviceStateManagerFoldProvider.kt b/packages/SystemUI/shared/src/com/android/systemui/unfold/system/DeviceStateManagerFoldProvider.kt
new file mode 100644
index 0000000..3b8d318
--- /dev/null
+++ b/packages/SystemUI/shared/src/com/android/systemui/unfold/system/DeviceStateManagerFoldProvider.kt
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+package com.android.systemui.unfold.system
+
+import android.content.Context
+import android.hardware.devicestate.DeviceStateManager
+import com.android.systemui.unfold.updates.FoldProvider
+import com.android.systemui.unfold.updates.FoldProvider.FoldCallback
+import java.util.concurrent.Executor
+import javax.inject.Inject
+import javax.inject.Singleton
+
+@Singleton
+class DeviceStateManagerFoldProvider @Inject constructor(
+    private val deviceStateManager: DeviceStateManager,
+    private val context: Context
+) : FoldProvider {
+
+    private val callbacks: MutableMap<FoldCallback,
+            DeviceStateManager.DeviceStateCallback> = hashMapOf()
+
+    override fun registerCallback(callback: FoldCallback, executor: Executor) {
+        val listener = FoldStateListener(context, callback)
+        deviceStateManager.registerCallback(executor, listener)
+        callbacks[callback] = listener
+    }
+
+    override fun unregisterCallback(callback: FoldCallback) {
+        val listener = callbacks.remove(callback)
+        listener?.let {
+            deviceStateManager.unregisterCallback(it)
+        }
+    }
+
+    private inner class FoldStateListener(
+        context: Context,
+        listener: FoldCallback
+    ) : DeviceStateManager.FoldStateListener(context, { listener.onFoldUpdated(it) })
+}
diff --git a/packages/SystemUI/shared/src/com/android/systemui/unfold/system/SystemUnfoldSharedModule.kt b/packages/SystemUI/shared/src/com/android/systemui/unfold/system/SystemUnfoldSharedModule.kt
new file mode 100644
index 0000000..24ae42a
--- /dev/null
+++ b/packages/SystemUI/shared/src/com/android/systemui/unfold/system/SystemUnfoldSharedModule.kt
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+package com.android.systemui.unfold.system
+
+import android.os.Handler
+import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.dagger.qualifiers.UiBackground
+import com.android.systemui.unfold.config.ResourceUnfoldTransitionConfig
+import com.android.systemui.unfold.config.UnfoldTransitionConfig
+import com.android.systemui.unfold.dagger.UnfoldBackground
+import com.android.systemui.unfold.dagger.UnfoldMain
+import com.android.systemui.unfold.updates.FoldProvider
+import com.android.systemui.unfold.util.CurrentActivityTypeProvider
+import dagger.Binds
+import dagger.Module
+import java.util.concurrent.Executor
+
+/**
+ * Dagger module with system-only dependencies for the unfold animation.
+ * The code that is used to calculate unfold transition progress
+ * depends on some hidden APIs that are not available in normal
+ * apps. In order to re-use this code and use alternative implementations
+ * of these classes in other apps and hidden APIs here.
+ */
+@Module
+abstract class SystemUnfoldSharedModule {
+
+    @Binds
+    abstract fun activityTypeProvider(executor: ActivityManagerActivityTypeProvider):
+            CurrentActivityTypeProvider
+
+    @Binds
+    abstract fun config(config: ResourceUnfoldTransitionConfig): UnfoldTransitionConfig
+
+    @Binds
+    abstract fun foldState(provider: DeviceStateManagerFoldProvider): FoldProvider
+
+    @Binds
+    @UnfoldMain
+    abstract fun mainExecutor(@Main executor: Executor): Executor
+
+    @Binds
+    @UnfoldMain
+    abstract fun mainHandler(@Main handler: Handler): Handler
+
+    @Binds
+    @UnfoldBackground
+    abstract fun backgroundExecutor(@UiBackground executor: Executor): Executor
+}
diff --git a/packages/SystemUI/shared/src/com/android/systemui/unfold/updates/DeviceFoldStateProvider.kt b/packages/SystemUI/shared/src/com/android/systemui/unfold/updates/DeviceFoldStateProvider.kt
deleted file mode 100644
index 14581cc..0000000
--- a/packages/SystemUI/shared/src/com/android/systemui/unfold/updates/DeviceFoldStateProvider.kt
+++ /dev/null
@@ -1,240 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.systemui.unfold.updates
-
-import android.annotation.FloatRange
-import android.app.ActivityManager
-import android.app.WindowConfiguration.ACTIVITY_TYPE_HOME
-import android.content.Context
-import android.hardware.devicestate.DeviceStateManager
-import android.os.Handler
-import android.util.Log
-import androidx.annotation.VisibleForTesting
-import androidx.core.util.Consumer
-import com.android.systemui.dagger.qualifiers.Main
-import com.android.systemui.unfold.updates.FoldStateProvider.FoldUpdate
-import com.android.systemui.unfold.updates.FoldStateProvider.FoldUpdatesListener
-import com.android.systemui.unfold.updates.hinge.FULLY_CLOSED_DEGREES
-import com.android.systemui.unfold.updates.hinge.FULLY_OPEN_DEGREES
-import com.android.systemui.unfold.updates.hinge.HingeAngleProvider
-import com.android.systemui.unfold.updates.screen.ScreenStatusProvider
-import java.util.concurrent.Executor
-import javax.inject.Inject
-
-class DeviceFoldStateProvider
-@Inject
-constructor(
-    context: Context,
-    private val hingeAngleProvider: HingeAngleProvider,
-    private val screenStatusProvider: ScreenStatusProvider,
-    private val deviceStateManager: DeviceStateManager,
-    private val activityManager: ActivityManager,
-    @Main private val mainExecutor: Executor,
-    @Main private val handler: Handler
-) : FoldStateProvider {
-
-    private val outputListeners: MutableList<FoldUpdatesListener> = mutableListOf()
-
-    @FoldUpdate private var lastFoldUpdate: Int? = null
-
-    @FloatRange(from = 0.0, to = 180.0) private var lastHingeAngle: Float = 0f
-
-    private val hingeAngleListener = HingeAngleListener()
-    private val screenListener = ScreenStatusListener()
-    private val foldStateListener = FoldStateListener(context)
-    private val timeoutRunnable = TimeoutRunnable()
-
-    /**
-     * 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.
-     */
-    private val halfOpenedTimeoutMillis: Int =
-        context.resources.getInteger(
-            com.android.internal.R.integer.config_unfoldTransitionHalfFoldedTimeout)
-
-    private var isFolded = false
-    private var isUnfoldHandled = true
-
-    override fun start() {
-        deviceStateManager.registerCallback(mainExecutor, foldStateListener)
-        screenStatusProvider.addCallback(screenListener)
-        hingeAngleProvider.addCallback(hingeAngleListener)
-    }
-
-    override fun stop() {
-        screenStatusProvider.removeCallback(screenListener)
-        deviceStateManager.unregisterCallback(foldStateListener)
-        hingeAngleProvider.removeCallback(hingeAngleListener)
-        hingeAngleProvider.stop()
-    }
-
-    override fun addCallback(listener: FoldUpdatesListener) {
-        outputListeners.add(listener)
-    }
-
-    override fun removeCallback(listener: FoldUpdatesListener) {
-        outputListeners.remove(listener)
-    }
-
-    override val isFinishedOpening: Boolean
-        get() = !isFolded &&
-            (lastFoldUpdate == FOLD_UPDATE_FINISH_FULL_OPEN ||
-                lastFoldUpdate == FOLD_UPDATE_FINISH_HALF_OPEN)
-
-    private val isTransitionInProgress: Boolean
-        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")
-        }
-
-        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
-
-        if (isClosing && closingThresholdMet && !closingEventDispatched && !isFullyOpened) {
-            notifyFoldUpdate(FOLD_UPDATE_START_CLOSING)
-        }
-
-        if (isTransitionInProgress) {
-            if (isFullyOpened) {
-                notifyFoldUpdate(FOLD_UPDATE_FINISH_FULL_OPEN)
-                cancelTimeout()
-            } else {
-                // The timeout will trigger some constant time after the last angle update.
-                rescheduleAbortAnimationTimeout()
-            }
-        }
-
-        lastHingeAngle = angle
-        outputListeners.forEach { it.onHingeAngleUpdate(angle) }
-    }
-
-    /**
-     * Fold animation should be started only after the threshold returned here.
-     *
-     * This has been introduced because the fold animation might be distracting/unwanted on top of
-     * apps that support table-top/HALF_FOLDED mode. Only for launcher, there is no threshold.
-     */
-    private fun getClosingThreshold(): Int? {
-        val activityType =
-            activityManager.getRunningTasks(/* maxNum= */ 1)?.getOrNull(0)?.topActivityType
-                ?: return null
-
-        if (DEBUG) {
-            Log.d(TAG, "activityType=" + activityType)
-        }
-
-        return if (activityType == ACTIVITY_TYPE_HOME) {
-            null
-        } else {
-            START_CLOSING_ON_APPS_THRESHOLD_DEGREES
-        }
-    }
-
-    private inner class FoldStateListener(context: Context) :
-        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()
-                }
-            })
-
-    private fun notifyFoldUpdate(@FoldUpdate update: Int) {
-        if (DEBUG) {
-            Log.d(TAG, stateToString(update))
-        }
-        outputListeners.forEach { it.onFoldUpdate(update) }
-        lastFoldUpdate = update
-    }
-
-    private fun rescheduleAbortAnimationTimeout() {
-        if (isTransitionInProgress) {
-            cancelTimeout()
-        }
-        handler.postDelayed(timeoutRunnable, halfOpenedTimeoutMillis.toLong())
-    }
-
-    private fun cancelTimeout() {
-        handler.removeCallbacks(timeoutRunnable)
-    }
-
-    private inner class ScreenStatusListener : ScreenStatusProvider.ScreenListener {
-
-        override fun onScreenTurnedOn() {
-            // Trigger this event only if we are unfolded and this is the first screen
-            // turned on event since unfold started. This prevents running the animation when
-            // turning on the internal display using the power button.
-            // Initially isUnfoldHandled is true so it will be reset to false *only* when we
-            // receive 'folded' event. If SystemUI started when device is already folded it will
-            // still receive 'folded' event on startup.
-            if (!isFolded && !isUnfoldHandled) {
-                outputListeners.forEach { it.onFoldUpdate(FOLD_UPDATE_UNFOLDED_SCREEN_AVAILABLE) }
-                isUnfoldHandled = true
-            }
-        }
-    }
-
-    private inner class HingeAngleListener : Consumer<Float> {
-        override fun accept(angle: Float) {
-            onHingeAngle(angle)
-        }
-    }
-
-    private inner class TimeoutRunnable : Runnable {
-        override fun run() {
-            notifyFoldUpdate(FOLD_UPDATE_FINISH_HALF_OPEN)
-        }
-    }
-}
-
-private fun stateToString(@FoldUpdate update: Int): String {
-    return when (update) {
-        FOLD_UPDATE_START_OPENING -> "START_OPENING"
-        FOLD_UPDATE_START_CLOSING -> "START_CLOSING"
-        FOLD_UPDATE_UNFOLDED_SCREEN_AVAILABLE -> "UNFOLDED_SCREEN_AVAILABLE"
-        FOLD_UPDATE_FINISH_HALF_OPEN -> "FINISH_HALF_OPEN"
-        FOLD_UPDATE_FINISH_FULL_OPEN -> "FINISH_FULL_OPEN"
-        FOLD_UPDATE_FINISH_CLOSED -> "FINISH_CLOSED"
-        else -> "UNKNOWN"
-    }
-}
-
-private const val TAG = "DeviceFoldProvider"
-private const val DEBUG = false
-
-/** Threshold after which we consider the device fully unfolded. */
-@VisibleForTesting const val FULLY_OPEN_THRESHOLD_DEGREES = 15f
-
-/** Fold animation on top of apps only when the angle exceeds this threshold. */
-@VisibleForTesting const val START_CLOSING_ON_APPS_THRESHOLD_DEGREES = 60
diff --git a/packages/SystemUI/shared/src/com/android/systemui/unfold/updates/FoldStateProvider.kt b/packages/SystemUI/shared/src/com/android/systemui/unfold/updates/FoldStateProvider.kt
deleted file mode 100644
index 14a3a70..0000000
--- a/packages/SystemUI/shared/src/com/android/systemui/unfold/updates/FoldStateProvider.kt
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.systemui.unfold.updates
-
-import android.annotation.FloatRange
-import android.annotation.IntDef
-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,
- * start folding/unfolding, screen availability
- */
-interface FoldStateProvider : CallbackController<FoldUpdatesListener> {
-    fun start()
-    fun stop()
-
-    val isFinishedOpening: Boolean
-
-    interface FoldUpdatesListener {
-        fun onHingeAngleUpdate(@FloatRange(from = 0.0, to = 180.0) angle: Float)
-        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])
-    @Retention(AnnotationRetention.SOURCE)
-    annotation class FoldUpdate
-}
-
-const val FOLD_UPDATE_START_OPENING = 0
-const val FOLD_UPDATE_START_CLOSING = 1
-const val FOLD_UPDATE_UNFOLDED_SCREEN_AVAILABLE = 2
-const val FOLD_UPDATE_FINISH_HALF_OPEN = 3
-const val FOLD_UPDATE_FINISH_FULL_OPEN = 4
-const val FOLD_UPDATE_FINISH_CLOSED = 5
diff --git a/packages/SystemUI/shared/src/com/android/systemui/unfold/updates/hinge/EmptyHingeAngleProvider.kt b/packages/SystemUI/shared/src/com/android/systemui/unfold/updates/hinge/EmptyHingeAngleProvider.kt
deleted file mode 100644
index b351585..0000000
--- a/packages/SystemUI/shared/src/com/android/systemui/unfold/updates/hinge/EmptyHingeAngleProvider.kt
+++ /dev/null
@@ -1,13 +0,0 @@
-package com.android.systemui.unfold.updates.hinge
-
-import androidx.core.util.Consumer
-
-internal object EmptyHingeAngleProvider : HingeAngleProvider {
-    override fun start() {}
-
-    override fun stop() {}
-
-    override fun removeCallback(listener: Consumer<Float>) {}
-
-    override fun addCallback(listener: Consumer<Float>) {}
-}
diff --git a/packages/SystemUI/shared/src/com/android/systemui/unfold/updates/hinge/HingeAngleProvider.kt b/packages/SystemUI/shared/src/com/android/systemui/unfold/updates/hinge/HingeAngleProvider.kt
deleted file mode 100644
index 48a5b12..0000000
--- a/packages/SystemUI/shared/src/com/android/systemui/unfold/updates/hinge/HingeAngleProvider.kt
+++ /dev/null
@@ -1,19 +0,0 @@
-package com.android.systemui.unfold.updates.hinge
-
-import androidx.core.util.Consumer
-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.
- */
-interface HingeAngleProvider : CallbackController<Consumer<Float>> {
-    fun start()
-    fun stop()
-}
-
-const val FULLY_OPEN_DEGREES = 180f
-const val FULLY_CLOSED_DEGREES = 0f
diff --git a/packages/SystemUI/shared/src/com/android/systemui/unfold/updates/hinge/HingeSensorAngleProvider.kt b/packages/SystemUI/shared/src/com/android/systemui/unfold/updates/hinge/HingeSensorAngleProvider.kt
deleted file mode 100644
index c93412b..0000000
--- a/packages/SystemUI/shared/src/com/android/systemui/unfold/updates/hinge/HingeSensorAngleProvider.kt
+++ /dev/null
@@ -1,51 +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 android.os.Trace
-import androidx.core.util.Consumer
-import java.util.concurrent.Executor
-
-internal class HingeSensorAngleProvider(
-    private val sensorManager: SensorManager,
-    private val executor: Executor
-) :
-    HingeAngleProvider {
-
-    private val sensorListener = HingeAngleSensorListener()
-    private val listeners: MutableList<Consumer<Float>> = arrayListOf()
-
-    override fun start() = executor.execute {
-        Trace.beginSection("HingeSensorAngleProvider#start")
-        val sensor = sensorManager.getDefaultSensor(Sensor.TYPE_HINGE_ANGLE)
-        sensorManager.registerListener(
-            sensorListener,
-            sensor,
-            SensorManager.SENSOR_DELAY_FASTEST
-        )
-        Trace.endSection()
-    }
-
-    override fun stop() = executor.execute {
-        sensorManager.unregisterListener(sensorListener)
-    }
-
-    override fun removeCallback(listener: Consumer<Float>) {
-        listeners.remove(listener)
-    }
-
-    override fun addCallback(listener: Consumer<Float>) {
-        listeners.add(listener)
-    }
-
-    private inner class HingeAngleSensorListener : SensorEventListener {
-
-        override fun onAccuracyChanged(sensor: Sensor?, accuracy: Int) {}
-
-        override fun onSensorChanged(event: SensorEvent) {
-            listeners.forEach { it.accept(event.values[0]) }
-        }
-    }
-}
diff --git a/packages/SystemUI/shared/src/com/android/systemui/unfold/updates/screen/ScreenStatusProvider.kt b/packages/SystemUI/shared/src/com/android/systemui/unfold/updates/screen/ScreenStatusProvider.kt
deleted file mode 100644
index 668c694..0000000
--- a/packages/SystemUI/shared/src/com/android/systemui/unfold/updates/screen/ScreenStatusProvider.kt
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.systemui.unfold.updates.screen
-
-import com.android.systemui.statusbar.policy.CallbackController
-import com.android.systemui.unfold.updates.screen.ScreenStatusProvider.ScreenListener
-
-interface ScreenStatusProvider : CallbackController<ScreenListener> {
-
-    interface ScreenListener {
-        /**
-         * Called when the screen is on and ready (windows are drawn and screen blocker is removed)
-         */
-        fun onScreenTurnedOn()
-    }
-}
diff --git a/packages/SystemUI/shared/src/com/android/systemui/unfold/util/ATraceLoggerTransitionProgressListener.kt b/packages/SystemUI/shared/src/com/android/systemui/unfold/util/ATraceLoggerTransitionProgressListener.kt
deleted file mode 100644
index 1574c8d..0000000
--- a/packages/SystemUI/shared/src/com/android/systemui/unfold/util/ATraceLoggerTransitionProgressListener.kt
+++ /dev/null
@@ -1,36 +0,0 @@
-package com.android.systemui.unfold.util
-
-import android.os.Trace
-import com.android.systemui.unfold.UnfoldTransitionProgressProvider.TransitionProgressListener
-import javax.inject.Inject
-import javax.inject.Qualifier
-
-/**
- * Listener that logs start and end of the fold-unfold transition.
- *
- * [tracePrefix] arg helps in differentiating those. Currently, this is expected to be logged twice
- * for each fold/unfold: in (1) systemui and (2) launcher process.
- */
-class ATraceLoggerTransitionProgressListener
-@Inject
-internal constructor(@UnfoldTransitionATracePrefix tracePrefix: String) :
-    TransitionProgressListener {
-
-    private val traceName = "$tracePrefix#$UNFOLD_TRANSITION_TRACE_NAME"
-
-    override fun onTransitionStarted() {
-        Trace.beginAsyncSection(traceName, /* cookie= */ 0)
-    }
-
-    override fun onTransitionFinished() {
-        Trace.endAsyncSection(traceName, /* cookie= */ 0)
-    }
-
-    override fun onTransitionProgress(progress: Float) {
-        Trace.setCounter(traceName, (progress * 100).toLong())
-    }
-}
-
-private const val UNFOLD_TRANSITION_TRACE_NAME = "FoldUnfoldTransitionInProgress"
-
-@Qualifier annotation class UnfoldTransitionATracePrefix
diff --git a/packages/SystemUI/shared/src/com/android/systemui/unfold/util/NaturalRotationUnfoldProgressProvider.kt b/packages/SystemUI/shared/src/com/android/systemui/unfold/util/NaturalRotationUnfoldProgressProvider.kt
index 53c528f..ec938b2 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/unfold/util/NaturalRotationUnfoldProgressProvider.kt
+++ b/packages/SystemUI/shared/src/com/android/systemui/unfold/util/NaturalRotationUnfoldProgressProvider.kt
@@ -1,3 +1,17 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the
+ * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
 package com.android.systemui.unfold.util
 
 import android.content.Context
diff --git a/packages/SystemUI/shared/src/com/android/systemui/unfold/util/ScaleAwareTransitionProgressProvider.kt b/packages/SystemUI/shared/src/com/android/systemui/unfold/util/ScaleAwareTransitionProgressProvider.kt
deleted file mode 100644
index dfe8792..0000000
--- a/packages/SystemUI/shared/src/com/android/systemui/unfold/util/ScaleAwareTransitionProgressProvider.kt
+++ /dev/null
@@ -1,63 +0,0 @@
-package com.android.systemui.unfold.util
-
-import android.animation.ValueAnimator
-import android.content.ContentResolver
-import android.database.ContentObserver
-import android.provider.Settings
-import com.android.systemui.unfold.UnfoldTransitionProgressProvider
-import com.android.systemui.unfold.UnfoldTransitionProgressProvider.TransitionProgressListener
-import dagger.assisted.Assisted
-import dagger.assisted.AssistedFactory
-import dagger.assisted.AssistedInject
-
-/** Wraps [UnfoldTransitionProgressProvider] to disable transitions when animations are disabled. */
-class ScaleAwareTransitionProgressProvider
-@AssistedInject
-constructor(
-    @Assisted progressProviderToWrap: UnfoldTransitionProgressProvider,
-    private val contentResolver: ContentResolver
-) : UnfoldTransitionProgressProvider {
-
-    private val scopedUnfoldTransitionProgressProvider =
-        ScopedUnfoldTransitionProgressProvider(progressProviderToWrap)
-
-    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)
-        onAnimatorScaleChanged()
-    }
-
-    private fun onAnimatorScaleChanged() {
-        val animationsEnabled = ValueAnimator.areAnimatorsEnabled()
-        scopedUnfoldTransitionProgressProvider.setReadyToHandleTransition(animationsEnabled)
-    }
-
-    override fun addCallback(listener: TransitionProgressListener) {
-        scopedUnfoldTransitionProgressProvider.addCallback(listener)
-    }
-
-    override fun removeCallback(listener: TransitionProgressListener) {
-        scopedUnfoldTransitionProgressProvider.removeCallback(listener)
-    }
-
-    override fun destroy() {
-        contentResolver.unregisterContentObserver(animatorDurationScaleObserver)
-        scopedUnfoldTransitionProgressProvider.destroy()
-    }
-
-    @AssistedFactory
-    interface Factory {
-        fun wrap(
-            progressProvider: UnfoldTransitionProgressProvider
-        ): ScaleAwareTransitionProgressProvider
-    }
-}
diff --git a/packages/SystemUI/shared/src/com/android/systemui/unfold/util/ScopedUnfoldTransitionProgressProvider.kt b/packages/SystemUI/shared/src/com/android/systemui/unfold/util/ScopedUnfoldTransitionProgressProvider.kt
deleted file mode 100644
index 8491f83..0000000
--- a/packages/SystemUI/shared/src/com/android/systemui/unfold/util/ScopedUnfoldTransitionProgressProvider.kt
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.systemui.unfold.util
-
-import com.android.systemui.unfold.UnfoldTransitionProgressProvider
-import com.android.systemui.unfold.UnfoldTransitionProgressProvider.TransitionProgressListener
-
-/**
- * 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.
- */
-open class ScopedUnfoldTransitionProgressProvider
-@JvmOverloads
-constructor(source: UnfoldTransitionProgressProvider? = null) :
-    UnfoldTransitionProgressProvider, TransitionProgressListener {
-
-    private var source: UnfoldTransitionProgressProvider? = null
-
-    private val listeners: MutableList<TransitionProgressListener> = mutableListOf()
-
-    private var isReadyToHandleTransition = false
-    private var isTransitionRunning = false
-    private var lastTransitionProgress = PROGRESS_UNSET
-
-    init {
-        setSourceProvider(source)
-    }
-    /**
-     * 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?) {
-        source?.removeCallback(this)
-
-        if (provider != null) {
-            source = provider
-            provider.addCallback(this)
-        } else {
-            source = null
-        }
-    }
-
-    /**
-     * 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 it with readyToHandleTransition = false when listeners can't process the events.
-     */
-    fun setReadyToHandleTransition(isReadyToHandleTransition: Boolean) {
-        if (isTransitionRunning) {
-            if (isReadyToHandleTransition) {
-                listeners.forEach { it.onTransitionStarted() }
-                if (lastTransitionProgress != PROGRESS_UNSET) {
-                    listeners.forEach { it.onTransitionProgress(lastTransitionProgress) }
-                }
-            } else {
-                isTransitionRunning = false
-                listeners.forEach { it.onTransitionFinished() }
-            }
-        }
-        this.isReadyToHandleTransition = isReadyToHandleTransition
-    }
-
-    override fun addCallback(listener: TransitionProgressListener) {
-        listeners += listener
-    }
-
-    override fun removeCallback(listener: TransitionProgressListener) {
-        listeners -= listener
-    }
-
-    override fun destroy() {
-        source?.removeCallback(this)
-        source?.destroy()
-    }
-
-    override fun onTransitionStarted() {
-        isTransitionRunning = true
-        if (isReadyToHandleTransition) {
-            listeners.forEach { it.onTransitionStarted() }
-        }
-    }
-
-    override fun onTransitionProgress(progress: Float) {
-        if (isReadyToHandleTransition) {
-            listeners.forEach { it.onTransitionProgress(progress) }
-        }
-        lastTransitionProgress = progress
-    }
-
-    override fun onTransitionFinished() {
-        if (isReadyToHandleTransition) {
-            listeners.forEach { it.onTransitionFinished() }
-        }
-        isTransitionRunning = false
-        lastTransitionProgress = PROGRESS_UNSET
-    }
-
-    companion object {
-        private const val PROGRESS_UNSET = -1f
-    }
-}