• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2020 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.InsetsController.DEBUG;
20 
21 import android.annotation.Nullable;
22 import android.annotation.UiThread;
23 import android.content.res.CompatibilityInfo;
24 import android.graphics.Rect;
25 import android.os.Handler;
26 import android.os.Trace;
27 import android.util.Log;
28 import android.util.SparseArray;
29 import android.util.proto.ProtoOutputStream;
30 import android.view.InsetsController.AnimationType;
31 import android.view.InsetsController.LayoutInsetsDuringAnimation;
32 import android.view.WindowInsets.Type.InsetsType;
33 import android.view.WindowInsetsAnimation.Bounds;
34 import android.view.inputmethod.ImeTracker;
35 
36 /**
37  * Insets animation runner that uses {@link InsetsAnimationThread} to run the animation off from the
38  * main thread.
39  *
40  * @hide
41  */
42 public class InsetsAnimationThreadControlRunner implements InsetsAnimationControlRunner {
43 
44     private static final String TAG = "InsetsAnimThreadRunner";
45     private final InsetsAnimationControlImpl mControl;
46     private final InsetsAnimationControlCallbacks mOuterCallbacks;
47     private final Handler mMainThreadHandler;
48     private final InsetsAnimationControlCallbacks mCallbacks =
49             new InsetsAnimationControlCallbacks() {
50 
51         @Override
52         @UiThread
53         public <T extends InsetsAnimationControlRunner & InternalInsetsAnimationController>
54         void startAnimation(T runner, WindowInsetsAnimationControlListener listener, int types,
55                 WindowInsetsAnimation animation, Bounds bounds) {
56             // Animation will be started in constructor already.
57         }
58 
59         @Override
60         public void scheduleApplyChangeInsets(InsetsAnimationControlRunner runner) {
61             synchronized (mControl) {
62                 // This reads the surface position on the animation thread, but the surface position
63                 // would be updated on the UI thread, so we need this critical section.
64                 // See: updateSurfacePosition.
65                 mControl.applyChangeInsets(null /* outState */);
66             }
67         }
68 
69         @Override
70         public void notifyFinished(InsetsAnimationControlRunner runner, boolean shown) {
71             Trace.asyncTraceEnd(Trace.TRACE_TAG_VIEW,
72                     "InsetsAsyncAnimation: " + WindowInsets.Type.toString(runner.getTypes()),
73                     runner.getTypes());
74             InsetsController.releaseControls(mControl.getControls());
75             mMainThreadHandler.post(() ->
76                     mOuterCallbacks.notifyFinished(InsetsAnimationThreadControlRunner.this, shown));
77         }
78 
79         @Override
80         public void releaseSurfaceControlFromRt(SurfaceControl sc) {
81             if (DEBUG) Log.d(TAG, "releaseSurfaceControlFromRt");
82             // Since we don't push the SurfaceParams to the RT we can release directly
83             sc.release();
84         }
85 
86         @Override
87         public void reportPerceptible(int types, boolean perceptible) {
88             mMainThreadHandler.post(() -> mOuterCallbacks.reportPerceptible(types, perceptible));
89         }
90     };
91 
92     private final SurfaceParamsApplier mSurfaceParamsApplier = new SurfaceParamsApplier() {
93 
94         private final float[] mTmpFloat9 = new float[9];
95 
96         @Override
97         public void applySurfaceParams(SyncRtSurfaceTransactionApplier.SurfaceParams... params) {
98             final SurfaceControl.Transaction t = new SurfaceControl.Transaction();
99             for (int i = params.length - 1; i >= 0; i--) {
100                 SyncRtSurfaceTransactionApplier.applyParams(t, params[i], mTmpFloat9);
101             }
102             t.setFrameTimelineVsync(Choreographer.getInstance().getVsyncId());
103             t.apply();
104             t.close();
105         }
106     };
107 
108     @UiThread
InsetsAnimationThreadControlRunner(SparseArray<InsetsSourceControl> controls, @Nullable Rect frame, InsetsState state, WindowInsetsAnimationControlListener listener, @InsetsType int types, InsetsAnimationControlCallbacks controller, InsetsAnimationSpec insetsAnimationSpec, @AnimationType int animationType, @LayoutInsetsDuringAnimation int layoutInsetsDuringAnimation, CompatibilityInfo.Translator translator, Handler mainThreadHandler, @Nullable ImeTracker.Token statsToken)109     public InsetsAnimationThreadControlRunner(SparseArray<InsetsSourceControl> controls,
110             @Nullable Rect frame, InsetsState state, WindowInsetsAnimationControlListener listener,
111             @InsetsType int types, InsetsAnimationControlCallbacks controller,
112             InsetsAnimationSpec insetsAnimationSpec, @AnimationType int animationType,
113             @LayoutInsetsDuringAnimation int layoutInsetsDuringAnimation,
114             CompatibilityInfo.Translator translator, Handler mainThreadHandler,
115             @Nullable ImeTracker.Token statsToken) {
116         mMainThreadHandler = mainThreadHandler;
117         mOuterCallbacks = controller;
118         mControl = new InsetsAnimationControlImpl(controls, frame, state, listener, types,
119                 mCallbacks, mSurfaceParamsApplier, insetsAnimationSpec, animationType,
120                 layoutInsetsDuringAnimation, translator, statsToken);
121         InsetsAnimationThread.getHandler().post(() -> {
122             if (mControl.isCancelled()) {
123                 return;
124             }
125             Trace.asyncTraceBegin(Trace.TRACE_TAG_VIEW,
126                     "InsetsAsyncAnimation: " + WindowInsets.Type.toString(types), types);
127             listener.onReady(mControl, types);
128         });
129     }
130 
131     @Override
132     @UiThread
dumpDebug(ProtoOutputStream proto, long fieldId)133     public void dumpDebug(ProtoOutputStream proto, long fieldId) {
134         mControl.dumpDebug(proto, fieldId);
135     }
136 
137     @Override
138     @Nullable
getStatsToken()139     public ImeTracker.Token getStatsToken() {
140         return mControl.getStatsToken();
141     }
142 
143     @Override
144     @UiThread
getTypes()145     public int getTypes() {
146         return mControl.getTypes();
147     }
148 
149     @Override
150     @UiThread
getControllingTypes()151     public int getControllingTypes() {
152         return mControl.getControllingTypes();
153     }
154 
155     @Override
156     @UiThread
notifyControlRevoked(@nsetsType int types)157     public void notifyControlRevoked(@InsetsType int types) {
158         mControl.notifyControlRevoked(types);
159     }
160 
161     @Override
162     @UiThread
updateSurfacePosition(SparseArray<InsetsSourceControl> controls)163     public void updateSurfacePosition(SparseArray<InsetsSourceControl> controls) {
164         synchronized (mControl) {
165             // This is called from the UI thread, however, the surface position will be used on the
166             // animation thread, so we need this critical section. See: scheduleApplyChangeInsets.
167             mControl.updateSurfacePosition(controls);
168         }
169     }
170 
171     @Override
172     @UiThread
willUpdateSurface()173     public boolean willUpdateSurface() {
174         synchronized (mControl) {
175             // This is called from the UI thread, however, applyChangeInsets would be called on the
176             // animation thread, so we need this critical section to ensure this is not called
177             // during applyChangeInsets. See: scheduleApplyChangeInsets.
178             return mControl.willUpdateSurface();
179         }
180     }
181 
182     @Override
183     @UiThread
cancel()184     public void cancel() {
185         InsetsAnimationThread.getHandler().post(mControl::cancel);
186     }
187 
188     @Override
189     @UiThread
getAnimation()190     public WindowInsetsAnimation getAnimation() {
191         return mControl.getAnimation();
192     }
193 
194     @Override
getAnimationType()195     public int getAnimationType() {
196         return mControl.getAnimationType();
197     }
198 
199     @Override
getSurfaceParamsApplier()200     public SurfaceParamsApplier getSurfaceParamsApplier() {
201         return mSurfaceParamsApplier;
202     }
203 
204     @Override
updateLayoutInsetsDuringAnimation( @ayoutInsetsDuringAnimation int layoutInsetsDuringAnimation)205     public void updateLayoutInsetsDuringAnimation(
206             @LayoutInsetsDuringAnimation int layoutInsetsDuringAnimation) {
207         InsetsAnimationThread.getHandler().post(
208                 () -> mControl.updateLayoutInsetsDuringAnimation(layoutInsetsDuringAnimation));
209     }
210 }
211