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