1 /* <lambda>null2 * Copyright (C) 2024 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.systemui.keyguard.ui.view.layout.sections.transitions 18 19 import android.animation.Animator 20 import android.animation.ValueAnimator 21 import android.transition.Transition 22 import android.transition.TransitionValues 23 import android.view.ViewGroup 24 import com.android.app.animation.Interpolators 25 import com.android.systemui.plugins.clocks.ClockController 26 import com.android.systemui.shared.R as sharedR 27 28 class DefaultClockSteppingTransition(private val clock: ClockController) : Transition() { 29 init { 30 interpolator = Interpolators.LINEAR 31 duration = KEYGUARD_STATUS_VIEW_CUSTOM_CLOCK_MOVE_DURATION_MS 32 addTarget(clock.largeClock.view) 33 if (com.android.systemui.shared.Flags.clockReactiveSmartspaceLayout()) { 34 addTarget(sharedR.id.date_smartspace_view_large) 35 } 36 } 37 38 private fun captureValues(transitionValues: TransitionValues) { 39 transitionValues.values[PROP_BOUNDS_LEFT] = transitionValues.view.left 40 val locationInWindowTmp = IntArray(2) 41 transitionValues.view.getLocationInWindow(locationInWindowTmp) 42 transitionValues.values[PROP_X_IN_WINDOW] = locationInWindowTmp[0] 43 } 44 45 override fun captureEndValues(transitionValues: TransitionValues) { 46 captureValues(transitionValues) 47 } 48 49 override fun captureStartValues(transitionValues: TransitionValues) { 50 captureValues(transitionValues) 51 } 52 53 override fun createAnimator( 54 sceneRoot: ViewGroup, 55 startValues: TransitionValues?, 56 endValues: TransitionValues?, 57 ): Animator? { 58 if (startValues == null || endValues == null) { 59 return null 60 } 61 val anim = ValueAnimator.ofFloat(0f, 1f) 62 val fromLeft = startValues.values[PROP_BOUNDS_LEFT] as Int 63 val fromWindowX = startValues.values[PROP_X_IN_WINDOW] as Int 64 val toWindowX = endValues.values[PROP_X_IN_WINDOW] as Int 65 // Using windowX, to determine direction, instead of left, as in RTL the difference of 66 // toLeft - fromLeft is always positive, even when moving left. 67 val direction = if (toWindowX - fromWindowX > 0) 1 else -1 68 anim.addUpdateListener { animation: ValueAnimator -> 69 clock.largeClock.animations.onPositionUpdated( 70 fromLeft, 71 direction, 72 animation.animatedFraction, 73 ) 74 } 75 return anim 76 } 77 78 override fun getTransitionProperties(): Array<String> { 79 return TRANSITION_PROPERTIES 80 } 81 82 companion object { 83 private const val PROP_BOUNDS_LEFT = "DefaultClockSteppingTransition:boundsLeft" 84 private const val PROP_X_IN_WINDOW = "DefaultClockSteppingTransition:xInWindow" 85 private val TRANSITION_PROPERTIES = arrayOf(PROP_BOUNDS_LEFT, PROP_X_IN_WINDOW) 86 private const val KEYGUARD_STATUS_VIEW_CUSTOM_CLOCK_MOVE_DURATION_MS = 1000L 87 } 88 } 89