1 /*
2  * Copyright (C) 2019 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.server.wm;
18 
19 import android.annotation.NonNull;
20 import android.annotation.Nullable;
21 import android.view.SurfaceControl;
22 
23 import java.util.function.BiConsumer;
24 import java.util.function.Consumer;
25 import java.util.function.Supplier;
26 
27 /**
28  * An implementation of {@link SurfaceAnimator.Animatable} that is instantiated
29  * using a builder pattern for more convenience over reimplementing the whole interface.
30  * <p>
31  * Use {@link SimpleSurfaceAnimatable.Builder} to create a new instance of this class.
32  *
33  * @see com.android.server.wm.SurfaceAnimator.Animatable
34  */
35 public class SimpleSurfaceAnimatable implements SurfaceAnimator.Animatable {
36     private final int mWidth;
37     private final int mHeight;
38     private final boolean mShouldDeferAnimationFinish;
39     private final SurfaceControl mAnimationLeashParent;
40     private final SurfaceControl mSurfaceControl;
41     private final SurfaceControl mParentSurfaceControl;
42     private final Runnable mCommitTransactionRunnable;
43     private final Supplier<SurfaceControl.Builder> mAnimationLeashFactory;
44     private final Supplier<SurfaceControl.Transaction> mSyncTransaction;
45     private final Supplier<SurfaceControl.Transaction> mPendingTransaction;
46     private final BiConsumer<SurfaceControl.Transaction, SurfaceControl> mOnAnimationLeashCreated;
47     private final Consumer<SurfaceControl.Transaction> mOnAnimationLeashLost;
48     private final Consumer<Runnable> mOnAnimationFinished;
49 
50     /**
51      * Use {@link SimpleSurfaceAnimatable.Builder} to create a new instance.
52      */
SimpleSurfaceAnimatable(Builder builder)53     private SimpleSurfaceAnimatable(Builder builder) {
54         mWidth = builder.mWidth;
55         mHeight = builder.mHeight;
56         mShouldDeferAnimationFinish = builder.mShouldDeferAnimationFinish;
57         mAnimationLeashParent = builder.mAnimationLeashParent;
58         mSurfaceControl = builder.mSurfaceControl;
59         mParentSurfaceControl = builder.mParentSurfaceControl;
60         mCommitTransactionRunnable = builder.mCommitTransactionRunnable;
61         mAnimationLeashFactory = builder.mAnimationLeashFactory;
62         mOnAnimationLeashCreated = builder.mOnAnimationLeashCreated;
63         mOnAnimationLeashLost = builder.mOnAnimationLeashLost;
64         mSyncTransaction = builder.mSyncTransactionSupplier;
65         mPendingTransaction = builder.mPendingTransactionSupplier;
66         mOnAnimationFinished = builder.mOnAnimationFinished;
67     }
68 
69     @Override
getSyncTransaction()70     public SurfaceControl.Transaction getSyncTransaction() {
71         return mSyncTransaction.get();
72     }
73 
74     @NonNull
75     @Override
getPendingTransaction()76     public SurfaceControl.Transaction getPendingTransaction() {
77         return mPendingTransaction.get();
78     }
79 
80     @Override
commitPendingTransaction()81     public void commitPendingTransaction() {
82         mCommitTransactionRunnable.run();
83     }
84 
85     @Override
onAnimationLeashCreated(SurfaceControl.Transaction t, SurfaceControl leash)86     public void onAnimationLeashCreated(SurfaceControl.Transaction t, SurfaceControl leash) {
87         if (mOnAnimationLeashCreated != null) {
88             mOnAnimationLeashCreated.accept(t, leash);
89         }
90 
91     }
92 
93     @Override
onAnimationLeashLost(SurfaceControl.Transaction t)94     public void onAnimationLeashLost(SurfaceControl.Transaction t) {
95         if (mOnAnimationLeashLost != null) {
96             mOnAnimationLeashLost.accept(t);
97         }
98     }
99 
100     @Override
101     @NonNull
makeAnimationLeash()102     public SurfaceControl.Builder makeAnimationLeash() {
103         return mAnimationLeashFactory.get();
104     }
105 
106     @Override
getAnimationLeashParent()107     public SurfaceControl getAnimationLeashParent() {
108         return mAnimationLeashParent;
109     }
110 
111     @Override
112     @Nullable
getSurfaceControl()113     public SurfaceControl getSurfaceControl() {
114         return mSurfaceControl;
115     }
116 
117     @Override
getParentSurfaceControl()118     public SurfaceControl getParentSurfaceControl() {
119         return mParentSurfaceControl;
120     }
121 
122     @Override
getSurfaceWidth()123     public int getSurfaceWidth() {
124         return mWidth;
125     }
126 
127     @Override
getSurfaceHeight()128     public int getSurfaceHeight() {
129         return mHeight;
130     }
131 
132     @Override
shouldDeferAnimationFinish(Runnable endDeferFinishCallback)133     public boolean shouldDeferAnimationFinish(Runnable endDeferFinishCallback) {
134         if (mOnAnimationFinished != null) {
135             mOnAnimationFinished.accept(endDeferFinishCallback);
136         }
137         return mShouldDeferAnimationFinish;
138     }
139 
140     /**
141      * Builder class to create a {@link SurfaceAnimator.Animatable} without having to
142      * create a new class that implements the interface.
143      */
144     static class Builder {
145         private int mWidth = -1;
146         private int mHeight = -1;
147         private boolean mShouldDeferAnimationFinish = false;
148 
149         @Nullable
150         private SurfaceControl mAnimationLeashParent = null;
151 
152         @Nullable
153         private SurfaceControl mSurfaceControl = null;
154 
155         @Nullable
156         private SurfaceControl mParentSurfaceControl = null;
157         private Runnable mCommitTransactionRunnable;
158 
159         @Nullable
160         private BiConsumer<SurfaceControl.Transaction, SurfaceControl> mOnAnimationLeashCreated =
161                 null;
162 
163         @Nullable
164         private Consumer<SurfaceControl.Transaction> mOnAnimationLeashLost = null;
165 
166         @Nullable
167         private Consumer<Runnable> mOnAnimationFinished = null;
168 
169         @NonNull
170         private Supplier<SurfaceControl.Transaction> mSyncTransactionSupplier;
171 
172         @NonNull
173         private Supplier<SurfaceControl.Transaction> mPendingTransactionSupplier;
174 
175         @NonNull
176         private Supplier<SurfaceControl.Builder> mAnimationLeashFactory;
177 
178         /**
179          * Set the runnable to be called when
180          * {@link SurfaceAnimator.Animatable#commitPendingTransaction()}
181          * is called.
182          *
183          * @see SurfaceAnimator.Animatable#commitPendingTransaction()
184          */
setCommitTransactionRunnable( @onNull Runnable commitTransactionRunnable)185         public SimpleSurfaceAnimatable.Builder setCommitTransactionRunnable(
186                 @NonNull Runnable commitTransactionRunnable) {
187             mCommitTransactionRunnable = commitTransactionRunnable;
188             return this;
189         }
190 
191         /**
192          * Set the callback called when
193          * {@link SurfaceAnimator.Animatable#onAnimationLeashCreated(SurfaceControl.Transaction,
194          * SurfaceControl)} is called
195          *
196          * @see SurfaceAnimator.Animatable#onAnimationLeashCreated(SurfaceControl.Transaction,
197          * SurfaceControl)
198          */
setOnAnimationLeashCreated( @ullable BiConsumer<SurfaceControl.Transaction, SurfaceControl> onAnimationLeashCreated)199         public SimpleSurfaceAnimatable.Builder setOnAnimationLeashCreated(
200                 @Nullable BiConsumer<SurfaceControl.Transaction, SurfaceControl>
201                         onAnimationLeashCreated) {
202             mOnAnimationLeashCreated = onAnimationLeashCreated;
203             return this;
204         }
205 
206         /**
207          * Set the callback called when
208          * {@link SurfaceAnimator.Animatable#onAnimationLeashLost(SurfaceControl.Transaction)}
209          * (SurfaceControl.Transaction, SurfaceControl)} is called
210          *
211          * @see SurfaceAnimator.Animatable#onAnimationLeashLost(SurfaceControl.Transaction)
212          */
setOnAnimationLeashLost( @ullable Consumer<SurfaceControl.Transaction> onAnimationLeashLost)213         public SimpleSurfaceAnimatable.Builder setOnAnimationLeashLost(
214                 @Nullable Consumer<SurfaceControl.Transaction> onAnimationLeashLost) {
215             mOnAnimationLeashLost = onAnimationLeashLost;
216             return this;
217         }
218 
219         /**
220          * @see SurfaceAnimator.Animatable#getSyncTransaction()
221          */
setSyncTransactionSupplier( @onNull Supplier<SurfaceControl.Transaction> syncTransactionSupplier)222         public Builder setSyncTransactionSupplier(
223                 @NonNull Supplier<SurfaceControl.Transaction> syncTransactionSupplier) {
224             mSyncTransactionSupplier = syncTransactionSupplier;
225             return this;
226         }
227 
228         /**
229          * @see SurfaceAnimator.Animatable#getPendingTransaction()
230          */
setPendingTransactionSupplier( @onNull Supplier<SurfaceControl.Transaction> pendingTransactionSupplier)231         public Builder setPendingTransactionSupplier(
232                 @NonNull Supplier<SurfaceControl.Transaction> pendingTransactionSupplier) {
233             mPendingTransactionSupplier = pendingTransactionSupplier;
234             return this;
235         }
236 
237         /**
238          * Set the {@link Supplier} responsible for creating a new animation leash.
239          *
240          * @see SurfaceAnimator.Animatable#makeAnimationLeash()
241          */
setAnimationLeashSupplier( @onNull Supplier<SurfaceControl.Builder> animationLeashFactory)242         public SimpleSurfaceAnimatable.Builder setAnimationLeashSupplier(
243                 @NonNull Supplier<SurfaceControl.Builder> animationLeashFactory) {
244             mAnimationLeashFactory = animationLeashFactory;
245             return this;
246         }
247 
248         /**
249          * @see SurfaceAnimator.Animatable#getAnimationLeashParent()
250          */
setAnimationLeashParent( SurfaceControl animationLeashParent)251         public SimpleSurfaceAnimatable.Builder setAnimationLeashParent(
252                 SurfaceControl animationLeashParent) {
253             mAnimationLeashParent = animationLeashParent;
254             return this;
255         }
256 
257         /**
258          * @see SurfaceAnimator.Animatable#getSurfaceControl()
259          */
setSurfaceControl( @onNull SurfaceControl surfaceControl)260         public SimpleSurfaceAnimatable.Builder setSurfaceControl(
261                 @NonNull SurfaceControl surfaceControl) {
262             mSurfaceControl = surfaceControl;
263             return this;
264         }
265 
266         /**
267          * @see SurfaceAnimator.Animatable#getParentSurfaceControl()
268          */
setParentSurfaceControl( SurfaceControl parentSurfaceControl)269         public SimpleSurfaceAnimatable.Builder setParentSurfaceControl(
270                 SurfaceControl parentSurfaceControl) {
271             mParentSurfaceControl = parentSurfaceControl;
272             return this;
273         }
274 
275         /**
276          * Default to -1.
277          *
278          * @see SurfaceAnimator.Animatable#getSurfaceWidth()
279          */
setWidth(int width)280         public SimpleSurfaceAnimatable.Builder setWidth(int width) {
281             mWidth = width;
282             return this;
283         }
284 
285         /**
286          * Default to -1.
287          *
288          * @see SurfaceAnimator.Animatable#getSurfaceHeight()
289          */
setHeight(int height)290         public SimpleSurfaceAnimatable.Builder setHeight(int height) {
291             mHeight = height;
292             return this;
293         }
294 
295         /**
296          * Set the value returned by
297          * {@link SurfaceAnimator.Animatable#shouldDeferAnimationFinish(Runnable)}.
298          *
299          * @param onAnimationFinish will be called with the runnable to execute when the animation
300          *                          needs to be finished.
301          * @see SurfaceAnimator.Animatable#shouldDeferAnimationFinish(Runnable)
302          */
setShouldDeferAnimationFinish( boolean shouldDeferAnimationFinish, @Nullable Consumer<Runnable> onAnimationFinish)303         public SimpleSurfaceAnimatable.Builder setShouldDeferAnimationFinish(
304                 boolean shouldDeferAnimationFinish,
305                 @Nullable Consumer<Runnable> onAnimationFinish) {
306             mShouldDeferAnimationFinish = shouldDeferAnimationFinish;
307             mOnAnimationFinished = onAnimationFinish;
308             return this;
309         }
310 
build()311         public SurfaceAnimator.Animatable build() {
312             if (mSyncTransactionSupplier == null) {
313                 throw new IllegalArgumentException("mSyncTransactionSupplier cannot be null");
314             }
315             if (mPendingTransactionSupplier == null) {
316                 throw new IllegalArgumentException("mPendingTransactionSupplier cannot be null");
317             }
318             if (mAnimationLeashFactory == null) {
319                 throw new IllegalArgumentException("mAnimationLeashFactory cannot be null");
320             }
321             if (mCommitTransactionRunnable == null) {
322                 throw new IllegalArgumentException("mCommitTransactionRunnable cannot be null");
323             }
324             if (mSurfaceControl == null) {
325                 throw new IllegalArgumentException("mSurfaceControl cannot be null");
326             }
327             return new SimpleSurfaceAnimatable(this);
328         }
329     }
330 }
331