1 /*
2  * Copyright (C) 2018 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 android.view;
18 
19 import android.graphics.Insets;
20 
21 /**
22  * Interface that allows the application to listen to animation events for windows that cause
23  * insets.
24  * @hide pending unhide
25  */
26 public interface WindowInsetsAnimationListener {
27 
28     /**
29      * Called when an inset animation gets started.
30      *
31      * @param animation The animation that is about to start.
32      */
onStarted(InsetsAnimation animation)33     void onStarted(InsetsAnimation animation);
34 
35     /**
36      * Called when the insets change as part of running an animation. Note that even if multiple
37      * animations for different types are running, there will only be one progress callback per
38      * frame. The {@code insets} passed as an argument represents the overall state and will include
39      * all types, regardless of whether they are animating or not.
40      * <p>
41      * Note that insets dispatch is hierarchical: It will start at the root of the view hierarchy,
42      * and then traverse it and invoke the callback of the specific {@link View} being traversed.
43      * The callback may return a modified instance by calling {@link WindowInsets#inset(int, int, int, int)}
44      * to indicate that a part of the insets have been used to offset or clip its children, and the
45      * children shouldn't worry about that part anymore.
46      *
47      * @param insets The current insets.
48      * @return The insets to dispatch to the subtree of the hierarchy.
49      */
onProgress(WindowInsets insets)50     WindowInsets onProgress(WindowInsets insets);
51 
52     /**
53      * Called when an inset animation has finished.
54      *
55      * @param animation The animation that has finished running.
56      */
onFinished(InsetsAnimation animation)57     void onFinished(InsetsAnimation animation);
58 
59     /**
60      * Class representing an animation of a set of windows that cause insets.
61      */
62     class InsetsAnimation {
63 
64         private final @WindowInsets.Type.InsetType int mTypeMask;
65         private final Insets mLowerBound;
66         private final Insets mUpperBound;
67 
68         /**
69          * @hide
70          */
InsetsAnimation(int typeMask, Insets lowerBound, Insets upperBound)71         InsetsAnimation(int typeMask, Insets lowerBound, Insets upperBound) {
72             mTypeMask = typeMask;
73             mLowerBound = lowerBound;
74             mUpperBound = upperBound;
75         }
76 
77         /**
78          * @return The bitmask of {@link WindowInsets.Type.InsetType}s that are animating.
79          */
getTypeMask()80         public @WindowInsets.Type.InsetType int getTypeMask() {
81             return mTypeMask;
82         }
83 
84         /**
85          * Queries the lower inset bound of the animation. If the animation is about showing or
86          * hiding a window that cause insets, the lower bound is {@link Insets#NONE} and the upper
87          * bound is the same as {@link WindowInsets#getInsets(int)} for the fully shown state. This
88          * is the same as {@link WindowInsetsAnimationController#getHiddenStateInsets} and
89          * {@link WindowInsetsAnimationController#getShownStateInsets} in case the listener gets
90          * invoked because of an animation that originates from
91          * {@link WindowInsetsAnimationController}.
92          * <p>
93          * However, if the size of a window that causes insets is changing, these are the
94          * lower/upper bounds of that size animation.
95          * <p>
96          * There are no overlapping animations for a specific type, but there may be two animations
97          * running at the same time for different inset types.
98          *
99          * @see #getUpperBound()
100          * @see WindowInsetsAnimationController#getHiddenStateInsets
101          * TODO: It's a bit weird that these are global per window but onProgress is hierarchical.
102          * TODO: If multiple types are animating, querying the bound per type isn't possible. Should
103          * we:
104          * 1. Offer bounds by type here?
105          * 2. Restrict one animation to one single type only?
106          * Returning WindowInsets here isn't feasible in case of overlapping animations: We can't
107          * fill in the insets for the types from the other animation into the WindowInsets object
108          * as it's changing as well.
109          */
getLowerBound()110         public Insets getLowerBound() {
111             return mLowerBound;
112         }
113 
114         /**
115          * @see #getLowerBound()
116          * @see WindowInsetsAnimationController#getShownStateInsets
117          */
getUpperBound()118         public Insets getUpperBound() {
119             return mUpperBound;
120         }
121     }
122 }
123