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
- }
-}