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 package com.android.server.wm; 17 18 import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_REMOTE_ANIMATIONS; 19 import static com.android.server.wm.AnimationAdapterProto.REMOTE; 20 import static com.android.server.wm.RemoteAnimationAdapterWrapperProto.TARGET; 21 import static com.android.server.wm.SurfaceAnimator.ANIMATION_TYPE_WINDOW_ANIMATION; 22 23 import android.annotation.NonNull; 24 import android.graphics.Point; 25 import android.os.SystemClock; 26 import android.util.proto.ProtoOutputStream; 27 import android.view.RemoteAnimationTarget; 28 import android.view.SurfaceControl; 29 30 import com.android.internal.protolog.common.ProtoLog; 31 import com.android.server.wm.SurfaceAnimator.AnimationType; 32 33 import java.io.PrintWriter; 34 import java.util.ArrayList; 35 import java.util.function.Consumer; 36 37 /** 38 * An animation adapter for wallpaper windows. 39 */ 40 class WallpaperAnimationAdapter implements AnimationAdapter { 41 private static final String TAG = "WallpaperAnimationAdapter"; 42 43 private final WallpaperWindowToken mWallpaperToken; 44 private SurfaceControl mCapturedLeash; 45 private SurfaceAnimator.OnAnimationFinishedCallback mCapturedLeashFinishCallback; 46 private @AnimationType int mLastAnimationType; 47 48 private long mDurationHint; 49 private long mStatusBarTransitionDelay; 50 51 private Consumer<WallpaperAnimationAdapter> mAnimationCanceledRunnable; 52 private RemoteAnimationTarget mTarget; 53 WallpaperAnimationAdapter(WallpaperWindowToken wallpaperToken, long durationHint, long statusBarTransitionDelay, Consumer<WallpaperAnimationAdapter> animationCanceledRunnable)54 WallpaperAnimationAdapter(WallpaperWindowToken wallpaperToken, 55 long durationHint, long statusBarTransitionDelay, 56 Consumer<WallpaperAnimationAdapter> animationCanceledRunnable) { 57 mWallpaperToken = wallpaperToken; 58 mDurationHint = durationHint; 59 mStatusBarTransitionDelay = statusBarTransitionDelay; 60 mAnimationCanceledRunnable = animationCanceledRunnable; 61 } 62 63 /** 64 * Creates and starts remote animations for all the visible wallpaper windows. 65 * 66 * @return RemoteAnimationTarget[] targets for all the visible wallpaper windows 67 */ startWallpaperAnimations(DisplayContent displayContent, long durationHint, long statusBarTransitionDelay, Consumer<WallpaperAnimationAdapter> animationCanceledRunnable, ArrayList<WallpaperAnimationAdapter> adaptersOut)68 public static RemoteAnimationTarget[] startWallpaperAnimations(DisplayContent displayContent, 69 long durationHint, long statusBarTransitionDelay, 70 Consumer<WallpaperAnimationAdapter> animationCanceledRunnable, 71 ArrayList<WallpaperAnimationAdapter> adaptersOut) { 72 if (!shouldStartWallpaperAnimation(displayContent)) { 73 ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS, 74 "\tWallpaper of display=%s is not visible", displayContent); 75 return new RemoteAnimationTarget[0]; 76 } 77 final ArrayList<RemoteAnimationTarget> targets = new ArrayList<>(); 78 displayContent.forAllWallpaperWindows(wallpaperWindow -> { 79 final WallpaperAnimationAdapter wallpaperAdapter = new WallpaperAnimationAdapter( 80 wallpaperWindow, durationHint, statusBarTransitionDelay, 81 animationCanceledRunnable); 82 wallpaperWindow.startAnimation(wallpaperWindow.getPendingTransaction(), 83 wallpaperAdapter, false /* hidden */, ANIMATION_TYPE_WINDOW_ANIMATION); 84 targets.add(wallpaperAdapter.createRemoteAnimationTarget()); 85 adaptersOut.add(wallpaperAdapter); 86 }); 87 return targets.toArray(new RemoteAnimationTarget[targets.size()]); 88 } 89 shouldStartWallpaperAnimation(DisplayContent displayContent)90 static boolean shouldStartWallpaperAnimation(DisplayContent displayContent) { 91 return displayContent.mWallpaperController.isWallpaperVisible(); 92 } 93 94 /** 95 * Create a remote animation target for this animation adapter. 96 */ createRemoteAnimationTarget()97 RemoteAnimationTarget createRemoteAnimationTarget() { 98 mTarget = new RemoteAnimationTarget(-1, -1, getLeash(), false, null, null, 99 mWallpaperToken.getPrefixOrderIndex(), new Point(), null, null, 100 mWallpaperToken.getWindowConfiguration(), true, null, null, null, false); 101 return mTarget; 102 } 103 104 /** 105 * @return the leash for this animation (only valid after the wallpaper window surface animation 106 * has started). 107 */ getLeash()108 SurfaceControl getLeash() { 109 return mCapturedLeash; 110 } 111 112 /** 113 * @return the callback to call to clean up when the animation has finished. 114 */ getLeashFinishedCallback()115 SurfaceAnimator.OnAnimationFinishedCallback getLeashFinishedCallback() { 116 return mCapturedLeashFinishCallback; 117 } 118 119 /** 120 * @return the type of animation. 121 */ getLastAnimationType()122 @AnimationType int getLastAnimationType() { 123 return mLastAnimationType; 124 } 125 126 /** 127 * @return the wallpaper window 128 */ getToken()129 WallpaperWindowToken getToken() { 130 return mWallpaperToken; 131 } 132 133 @Override getShowWallpaper()134 public boolean getShowWallpaper() { 135 // Not used 136 return false; 137 } 138 139 @Override startAnimation(SurfaceControl animationLeash, SurfaceControl.Transaction t, @AnimationType int type, @NonNull SurfaceAnimator.OnAnimationFinishedCallback finishCallback)140 public void startAnimation(SurfaceControl animationLeash, SurfaceControl.Transaction t, 141 @AnimationType int type, 142 @NonNull SurfaceAnimator.OnAnimationFinishedCallback finishCallback) { 143 ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS, "startAnimation"); 144 145 // Restore z-layering until client has a chance to modify it. 146 t.setLayer(animationLeash, mWallpaperToken.getPrefixOrderIndex()); 147 mCapturedLeash = animationLeash; 148 mCapturedLeashFinishCallback = finishCallback; 149 mLastAnimationType = type; 150 } 151 152 @Override onAnimationCancelled(SurfaceControl animationLeash)153 public void onAnimationCancelled(SurfaceControl animationLeash) { 154 ProtoLog.d(WM_DEBUG_REMOTE_ANIMATIONS, "onAnimationCancelled"); 155 mAnimationCanceledRunnable.accept(this); 156 } 157 158 @Override getDurationHint()159 public long getDurationHint() { 160 return mDurationHint; 161 } 162 163 @Override getStatusBarTransitionsStartTime()164 public long getStatusBarTransitionsStartTime() { 165 return SystemClock.uptimeMillis() + mStatusBarTransitionDelay; 166 } 167 168 @Override dump(PrintWriter pw, String prefix)169 public void dump(PrintWriter pw, String prefix) { 170 pw.print(prefix); 171 pw.print("token="); 172 pw.println(mWallpaperToken); 173 if (mTarget != null) { 174 pw.print(prefix); 175 pw.println("Target:"); 176 mTarget.dump(pw, prefix + " "); 177 } else { 178 pw.print(prefix); 179 pw.println("Target: null"); 180 } 181 } 182 183 @Override dumpDebug(ProtoOutputStream proto)184 public void dumpDebug(ProtoOutputStream proto) { 185 final long token = proto.start(REMOTE); 186 if (mTarget != null) { 187 mTarget.dumpDebug(proto, TARGET); 188 } 189 proto.end(token); 190 } 191 } 192