• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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