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