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