Loading libs/dream/lowlight/src/com/android/dream/lowlight/LowLightDreamManager.kt +6 −0 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ import android.content.ComponentName import android.util.Log import com.android.dream.lowlight.dagger.LowLightDreamModule import com.android.dream.lowlight.dagger.qualifiers.Application import kotlinx.coroutines.CancellationException import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Job import kotlinx.coroutines.TimeoutCancellationException Loading Loading @@ -103,6 +104,11 @@ class LowLightDreamManager @Inject constructor( ) } catch (ex: TimeoutCancellationException) { Log.e(TAG, "timed out while waiting for low light animation", ex) } catch (ex: CancellationException) { Log.w(TAG, "low light transition animation cancelled") // Catch the cancellation so that we still set the system dream component if the // animation is cancelled, such as by a user tapping to wake as the transition to // low light happens. } dreamManager.setSystemDreamComponent( if (shouldEnterLowLight) lowLightDreamComponent else null Loading libs/dream/lowlight/src/com/android/dream/lowlight/LowLightTransitionCoordinator.kt +0 −10 Original line number Diff line number Diff line Loading @@ -110,15 +110,5 @@ class LowLightTransitionCoordinator @Inject constructor() { } } animator.addListener(listener) continuation.invokeOnCancellation { try { animator.removeListener(listener) animator.cancel() } catch (exception: IndexOutOfBoundsException) { // TODO(b/285666217): remove this try/catch once a proper fix is implemented. // Cancelling the animator can cause an exception since we may be removing a // listener during the cancellation. See b/285666217 for more details. } } } } libs/dream/lowlight/src/com/android/dream/lowlight/util/TruncatedInterpolator.kt 0 → 100644 +54 −0 Original line number Diff line number Diff line /* * Copyright (C) 2023 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.dream.lowlight.util import android.view.animation.Interpolator /** * Interpolator wrapper that shortens another interpolator from its original duration to a portion * of that duration. * * For example, an `originalDuration` of 1000 and a `newDuration` of 200 results in an animation * that when played for 200ms is the exact same as the first 200ms of a 1000ms animation if using * the original interpolator. * * This is useful for the transition between the user dream and the low light clock as some * animations are defined in the spec to be longer than the total duration of the animation. For * example, the low light clock exit translation animation is defined to last >1s while the actual * fade out of the low light clock is only 250ms, meaning the clock isn't visible anymore after * 250ms. * * Since the dream framework currently only allows one dream to be visible and running, we use this * interpolator to play just the first 250ms of the translation animation. Simply reducing the * duration of the animation would result in the text exiting much faster than intended, so a custom * interpolator is needed. */ class TruncatedInterpolator( private val baseInterpolator: Interpolator, originalDuration: Float, newDuration: Float ) : Interpolator { private val scaleFactor: Float init { scaleFactor = newDuration / originalDuration } override fun getInterpolation(input: Float): Float { return baseInterpolator.getInterpolation(input * scaleFactor) } } libs/dream/lowlight/tests/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ android_test { "androidx.test.runner", "androidx.test.rules", "androidx.test.ext.junit", "animationlib", "frameworks-base-testutils", "junit", "kotlinx_coroutines_test", Loading libs/dream/lowlight/tests/src/com.android.dream.lowlight/LowLightDreamManagerTest.kt +15 −0 Original line number Diff line number Diff line Loading @@ -152,6 +152,21 @@ class LowLightDreamManagerTest { verify(mDreamManager).setSystemDreamComponent(DREAM_COMPONENT) } @Test fun setAmbientLightMode_animationCancelled_SetsSystemDream() = testScope.runTest { mLowLightDreamManager.setAmbientLightMode(LowLightDreamManager.AMBIENT_LIGHT_MODE_LOW_LIGHT) runCurrent() cancelEnterAnimations() runCurrent() // Animation never finishes, but we should still set the system dream verify(mDreamManager).setSystemDreamComponent(DREAM_COMPONENT) } private fun cancelEnterAnimations() { val listener = withArgCaptor { verify(mEnterAnimator).addListener(capture()) } listener.onAnimationCancel(mEnterAnimator) } private fun completeEnterAnimations() { val listener = withArgCaptor { verify(mEnterAnimator).addListener(capture()) } listener.onAnimationEnd(mEnterAnimator) Loading Loading
libs/dream/lowlight/src/com/android/dream/lowlight/LowLightDreamManager.kt +6 −0 Original line number Diff line number Diff line Loading @@ -23,6 +23,7 @@ import android.content.ComponentName import android.util.Log import com.android.dream.lowlight.dagger.LowLightDreamModule import com.android.dream.lowlight.dagger.qualifiers.Application import kotlinx.coroutines.CancellationException import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Job import kotlinx.coroutines.TimeoutCancellationException Loading Loading @@ -103,6 +104,11 @@ class LowLightDreamManager @Inject constructor( ) } catch (ex: TimeoutCancellationException) { Log.e(TAG, "timed out while waiting for low light animation", ex) } catch (ex: CancellationException) { Log.w(TAG, "low light transition animation cancelled") // Catch the cancellation so that we still set the system dream component if the // animation is cancelled, such as by a user tapping to wake as the transition to // low light happens. } dreamManager.setSystemDreamComponent( if (shouldEnterLowLight) lowLightDreamComponent else null Loading
libs/dream/lowlight/src/com/android/dream/lowlight/LowLightTransitionCoordinator.kt +0 −10 Original line number Diff line number Diff line Loading @@ -110,15 +110,5 @@ class LowLightTransitionCoordinator @Inject constructor() { } } animator.addListener(listener) continuation.invokeOnCancellation { try { animator.removeListener(listener) animator.cancel() } catch (exception: IndexOutOfBoundsException) { // TODO(b/285666217): remove this try/catch once a proper fix is implemented. // Cancelling the animator can cause an exception since we may be removing a // listener during the cancellation. See b/285666217 for more details. } } } }
libs/dream/lowlight/src/com/android/dream/lowlight/util/TruncatedInterpolator.kt 0 → 100644 +54 −0 Original line number Diff line number Diff line /* * Copyright (C) 2023 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.dream.lowlight.util import android.view.animation.Interpolator /** * Interpolator wrapper that shortens another interpolator from its original duration to a portion * of that duration. * * For example, an `originalDuration` of 1000 and a `newDuration` of 200 results in an animation * that when played for 200ms is the exact same as the first 200ms of a 1000ms animation if using * the original interpolator. * * This is useful for the transition between the user dream and the low light clock as some * animations are defined in the spec to be longer than the total duration of the animation. For * example, the low light clock exit translation animation is defined to last >1s while the actual * fade out of the low light clock is only 250ms, meaning the clock isn't visible anymore after * 250ms. * * Since the dream framework currently only allows one dream to be visible and running, we use this * interpolator to play just the first 250ms of the translation animation. Simply reducing the * duration of the animation would result in the text exiting much faster than intended, so a custom * interpolator is needed. */ class TruncatedInterpolator( private val baseInterpolator: Interpolator, originalDuration: Float, newDuration: Float ) : Interpolator { private val scaleFactor: Float init { scaleFactor = newDuration / originalDuration } override fun getInterpolation(input: Float): Float { return baseInterpolator.getInterpolation(input * scaleFactor) } }
libs/dream/lowlight/tests/Android.bp +1 −0 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ android_test { "androidx.test.runner", "androidx.test.rules", "androidx.test.ext.junit", "animationlib", "frameworks-base-testutils", "junit", "kotlinx_coroutines_test", Loading
libs/dream/lowlight/tests/src/com.android.dream.lowlight/LowLightDreamManagerTest.kt +15 −0 Original line number Diff line number Diff line Loading @@ -152,6 +152,21 @@ class LowLightDreamManagerTest { verify(mDreamManager).setSystemDreamComponent(DREAM_COMPONENT) } @Test fun setAmbientLightMode_animationCancelled_SetsSystemDream() = testScope.runTest { mLowLightDreamManager.setAmbientLightMode(LowLightDreamManager.AMBIENT_LIGHT_MODE_LOW_LIGHT) runCurrent() cancelEnterAnimations() runCurrent() // Animation never finishes, but we should still set the system dream verify(mDreamManager).setSystemDreamComponent(DREAM_COMPONENT) } private fun cancelEnterAnimations() { val listener = withArgCaptor { verify(mEnterAnimator).addListener(capture()) } listener.onAnimationCancel(mEnterAnimator) } private fun completeEnterAnimations() { val listener = withArgCaptor { verify(mEnterAnimator).addListener(capture()) } listener.onAnimationEnd(mEnterAnimator) Loading