• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 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 static android.view.InsetsAnimationControlImplProto.CURRENT_ALPHA;
20 import static android.view.InsetsAnimationControlImplProto.IS_CANCELLED;
21 import static android.view.InsetsAnimationControlImplProto.IS_FINISHED;
22 import static android.view.InsetsAnimationControlImplProto.PENDING_ALPHA;
23 import static android.view.InsetsAnimationControlImplProto.PENDING_FRACTION;
24 import static android.view.InsetsAnimationControlImplProto.PENDING_INSETS;
25 import static android.view.InsetsAnimationControlImplProto.SHOWN_ON_FINISH;
26 import static android.view.InsetsAnimationControlImplProto.TMP_MATRIX;
27 import static android.view.InsetsController.ANIMATION_TYPE_RESIZE;
28 
29 import android.animation.Animator;
30 import android.animation.AnimatorListenerAdapter;
31 import android.animation.ValueAnimator;
32 import android.annotation.Nullable;
33 import android.graphics.Insets;
34 import android.graphics.Rect;
35 import android.util.SparseArray;
36 import android.util.proto.ProtoOutputStream;
37 import android.view.InsetsController.LayoutInsetsDuringAnimation;
38 import android.view.WindowInsets.Type.InsetsType;
39 import android.view.WindowInsetsAnimation.Bounds;
40 import android.view.animation.Interpolator;
41 import android.view.inputmethod.ImeTracker;
42 
43 /**
44  * Runs a fake animation of resizing insets to produce insets animation callbacks.
45  * @hide
46  */
47 public class InsetsResizeAnimationRunner implements InsetsAnimationControlRunner,
48         InternalInsetsAnimationController, WindowInsetsAnimationControlListener {
49 
50     private final InsetsState mFromState;
51     private final InsetsState mToState;
52     private final @InsetsType int mTypes;
53     private final WindowInsetsAnimation mAnimation;
54     private final InsetsAnimationControlCallbacks mController;
55     private ValueAnimator mAnimator;
56     private boolean mCancelled;
57     private boolean mFinished;
58 
InsetsResizeAnimationRunner(Rect frame, InsetsState fromState, InsetsState toState, Interpolator interpolator, long duration, @InsetsType int types, InsetsAnimationControlCallbacks controller)59     public InsetsResizeAnimationRunner(Rect frame, InsetsState fromState, InsetsState toState,
60             Interpolator interpolator, long duration, @InsetsType int types,
61             InsetsAnimationControlCallbacks controller) {
62         mFromState = fromState;
63         mToState = toState;
64         mTypes = types;
65         mController = controller;
66         mAnimation = new WindowInsetsAnimation(types, interpolator, duration);
67         mAnimation.setAlpha(1f);
68         final Insets fromInsets = fromState.calculateInsets(
69                 frame, types, false /* ignoreVisibility */);
70         final Insets toInsets = toState.calculateInsets(
71                 frame, types, false /* ignoreVisibility */);
72         controller.startAnimation(this, this, types, mAnimation,
73                 new Bounds(Insets.min(fromInsets, toInsets), Insets.max(fromInsets, toInsets)));
74     }
75 
76     @Override
getTypes()77     public int getTypes() {
78         return mTypes;
79     }
80 
81     @Override
getControllingTypes()82     public int getControllingTypes() {
83         return mTypes;
84     }
85 
86     @Override
getAnimation()87     public WindowInsetsAnimation getAnimation() {
88         return mAnimation;
89     }
90 
91     @Override
getAnimationType()92     public int getAnimationType() {
93         return ANIMATION_TYPE_RESIZE;
94     }
95 
96     @Override
getSurfaceParamsApplier()97     public SurfaceParamsApplier getSurfaceParamsApplier() {
98         return SurfaceParamsApplier.DEFAULT;
99     }
100 
101     @Override
102     @Nullable
getStatsToken()103     public ImeTracker.Token getStatsToken() {
104         // Return null as resizing the IME view is not explicitly tracked.
105         return null;
106     }
107 
108     @Override
cancel()109     public void cancel() {
110         if (mCancelled || mFinished) {
111             return;
112         }
113         mCancelled = true;
114         if (mAnimator != null) {
115             mAnimator.cancel();
116         }
117     }
118 
119     @Override
isCancelled()120     public boolean isCancelled() {
121         return mCancelled;
122     }
123 
124     @Override
onReady(WindowInsetsAnimationController controller, int types)125     public void onReady(WindowInsetsAnimationController controller, int types) {
126         if (mCancelled) {
127             return;
128         }
129         mAnimator = ValueAnimator.ofFloat(0f, 1f);
130         mAnimator.setDuration(mAnimation.getDurationMillis());
131         mAnimator.addUpdateListener(animation -> {
132             mAnimation.setFraction(animation.getAnimatedFraction());
133             mController.scheduleApplyChangeInsets(InsetsResizeAnimationRunner.this);
134         });
135         mAnimator.addListener(new AnimatorListenerAdapter() {
136 
137             @Override
138             public void onAnimationEnd(Animator animation) {
139                 mFinished = true;
140                 mController.scheduleApplyChangeInsets(InsetsResizeAnimationRunner.this);
141             }
142         });
143         mAnimator.start();
144     }
145 
146     @Override
applyChangeInsets(InsetsState outState)147     public boolean applyChangeInsets(InsetsState outState) {
148         if (mCancelled) {
149             return false;
150         }
151         final float fraction = mAnimation.getInterpolatedFraction();
152         InsetsState.traverse(mFromState, mToState, new InsetsState.OnTraverseCallbacks() {
153             @Override
154             public void onIdMatch(InsetsSource fromSource, InsetsSource toSource) {
155                 final Rect fromFrame = fromSource.getFrame();
156                 final Rect toFrame = toSource.getFrame();
157                 final Rect frame = new Rect(
158                         (int) (fromFrame.left + fraction * (toFrame.left - fromFrame.left)),
159                         (int) (fromFrame.top + fraction * (toFrame.top - fromFrame.top)),
160                         (int) (fromFrame.right + fraction * (toFrame.right - fromFrame.right)),
161                         (int) (fromFrame.bottom + fraction * (toFrame.bottom - fromFrame.bottom)));
162                 final InsetsSource source =
163                         new InsetsSource(fromSource.getId(), fromSource.getType());
164                 source.setFrame(frame);
165                 source.setVisible(toSource.isVisible());
166                 outState.addSource(source);
167             }
168         });
169         if (mFinished) {
170             mController.notifyFinished(this, true /* shown */);
171         }
172         return mFinished;
173     }
174 
175     @Override
dumpDebug(ProtoOutputStream proto, long fieldId)176     public void dumpDebug(ProtoOutputStream proto, long fieldId) {
177         final long token = proto.start(fieldId);
178         proto.write(IS_CANCELLED, mCancelled);
179         proto.write(IS_FINISHED, mFinished);
180         proto.write(TMP_MATRIX, "null");
181         proto.write(PENDING_INSETS, "null");
182         proto.write(PENDING_FRACTION, mAnimation.getInterpolatedFraction());
183         proto.write(SHOWN_ON_FINISH, true);
184         proto.write(CURRENT_ALPHA, 1f);
185         proto.write(PENDING_ALPHA, 1f);
186         proto.end(token);
187     }
188 
189     @Override
getHiddenStateInsets()190     public Insets getHiddenStateInsets() {
191         return Insets.NONE;
192     }
193 
194     @Override
getShownStateInsets()195     public Insets getShownStateInsets() {
196         return Insets.NONE;
197     }
198 
199     @Override
getCurrentInsets()200     public Insets getCurrentInsets() {
201         return Insets.NONE;
202     }
203 
204     @Override
getCurrentFraction()205     public float getCurrentFraction() {
206         return 0;
207     }
208 
209     @Override
getCurrentAlpha()210     public float getCurrentAlpha() {
211         return 0;
212     }
213 
214     @Override
setInsetsAndAlpha(Insets insets, float alpha, float fraction)215     public void setInsetsAndAlpha(Insets insets, float alpha, float fraction) {
216     }
217 
218     @Override
finish(boolean shown)219     public void finish(boolean shown) {
220     }
221 
222     @Override
isFinished()223     public boolean isFinished() {
224         return false;
225     }
226 
227     @Override
notifyControlRevoked(int types)228     public void notifyControlRevoked(int types) {
229     }
230 
231     @Override
updateSurfacePosition(SparseArray<InsetsSourceControl> controls)232     public void updateSurfacePosition(SparseArray<InsetsSourceControl> controls) {
233     }
234 
235     @Override
willUpdateSurface()236     public boolean willUpdateSurface() {
237         return false;
238     }
239 
240     @Override
hasZeroInsetsIme()241     public boolean hasZeroInsetsIme() {
242         return false;
243     }
244 
245     @Override
getDurationMs()246     public long getDurationMs() {
247         return 0;
248     }
249 
250     @Override
getInsetsInterpolator()251     public Interpolator getInsetsInterpolator() {
252         return null;
253     }
254 
255     @Override
setReadyDispatched(boolean dispatched)256     public void setReadyDispatched(boolean dispatched) {
257     }
258 
259     @Override
onFinished(WindowInsetsAnimationController controller)260     public void onFinished(WindowInsetsAnimationController controller) {
261     }
262 
263     @Override
onCancelled(WindowInsetsAnimationController controller)264     public void onCancelled(WindowInsetsAnimationController controller) {
265     }
266 
267     @Override
updateLayoutInsetsDuringAnimation( @ayoutInsetsDuringAnimation int layoutInsetsDuringAnimation)268     public void updateLayoutInsetsDuringAnimation(
269             @LayoutInsetsDuringAnimation int layoutInsetsDuringAnimation) {
270     }
271 }
272