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