1 /*
2 * Copyright (C) 2023 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.animation.back
18
19 import android.annotation.IntRange
20 import android.util.DisplayMetrics
21 import android.view.View
22 import android.window.BackEvent
23 import android.window.OnBackAnimationCallback
24 import android.window.OnBackInvokedDispatcher
25 import android.window.OnBackInvokedDispatcher.Priority
26
27 /**
28 * Generates an [OnBackAnimationCallback] given a [backAnimationSpec]. [onBackProgressed] will be
29 * called on each update passing the current [BackTransformation].
30 *
31 * Optionally, you can specify [onBackStarted], [onBackInvoked], and [onBackCancelled] callbacks.
32 *
33 * @sample com.android.systemui.util.registerAnimationOnBackInvoked
34 */
onBackAnimationCallbackFromnull35 fun onBackAnimationCallbackFrom(
36 backAnimationSpec: BackAnimationSpec,
37 displayMetrics: DisplayMetrics, // TODO(b/265060720): We could remove this
38 onBackProgressed: (BackTransformation) -> Unit,
39 onBackStarted: (BackEvent) -> Unit = {},
<lambda>null40 onBackInvoked: () -> Unit = {},
<lambda>null41 onBackCancelled: () -> Unit = {},
42 ): OnBackAnimationCallback {
43 return object : OnBackAnimationCallback {
44 private var initialY = 0f
45 private val lastTransformation = BackTransformation()
46
onBackStartednull47 override fun onBackStarted(backEvent: BackEvent) {
48 initialY = backEvent.touchY
49 onBackStarted(backEvent)
50 }
51
onBackProgressednull52 override fun onBackProgressed(backEvent: BackEvent) {
53 val progressY = (backEvent.touchY - initialY) / displayMetrics.heightPixels
54
55 backAnimationSpec.getBackTransformation(
56 backEvent = backEvent,
57 progressY = progressY,
58 result = lastTransformation,
59 )
60
61 onBackProgressed(lastTransformation)
62 }
63
onBackInvokednull64 override fun onBackInvoked() {
65 onBackInvoked()
66 }
67
onBackCancellednull68 override fun onBackCancelled() {
69 onBackCancelled()
70 }
71 }
72 }
73
74 /**
75 * Register [OnBackAnimationCallback] when View is attached and unregister it when View is detached
76 *
77 * @sample com.android.systemui.util.registerAnimationOnBackInvoked
78 */
registerOnBackInvokedCallbackOnViewAttachednull79 fun View.registerOnBackInvokedCallbackOnViewAttached(
80 onBackInvokedDispatcher: OnBackInvokedDispatcher,
81 onBackAnimationCallback: OnBackAnimationCallback,
82 @Priority @IntRange(from = 0) priority: Int = OnBackInvokedDispatcher.PRIORITY_DEFAULT,
83 ) {
84 addOnAttachStateChangeListener(
85 object : View.OnAttachStateChangeListener {
86 override fun onViewAttachedToWindow(v: View) {
87 onBackInvokedDispatcher.registerOnBackInvokedCallback(
88 priority,
89 onBackAnimationCallback
90 )
91 }
92
93 override fun onViewDetachedFromWindow(v: View) {
94 removeOnAttachStateChangeListener(this)
95 onBackInvokedDispatcher.unregisterOnBackInvokedCallback(onBackAnimationCallback)
96 }
97 }
98 )
99
100 if (isAttachedToWindow) {
101 onBackInvokedDispatcher.registerOnBackInvokedCallback(priority, onBackAnimationCallback)
102 }
103 }
104