blob: 6ff4b2e504f13bca9b32ad7a278b7db30657aae7 [file] [log] [blame]
Wale Ogunwalee8069dc2015-08-18 09:52:01 -07001/*
2 * Copyright (C) 2015 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
17package com.android.server.wm;
18
Wale Ogunwale44f036f2017-09-29 05:09:09 -070019import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM;
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -080020import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
Wale Ogunwalee8069dc2015-08-18 09:52:01 -070021import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
Jorim Jaggife762342016-10-13 14:33:27 +020022import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;
Wale Ogunwalee8069dc2015-08-18 09:52:01 -070023import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
lumark588a3e82018-07-20 18:53:54 +080024import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_WITH_WALLPAPER;
Jorim Jaggife762342016-10-13 14:33:27 +020025
Adrian Roose99bc052017-11-20 17:55:31 +010026import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
lumark9bca6b42019-10-17 18:35:22 +080027import static com.android.server.wm.WindowContainer.AnimationFlags.PARENTS;
28import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION;
chaviw0315a1a2018-03-05 15:28:35 -080029import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_SCREENSHOT;
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -080030import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER;
31import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER_LIGHT;
32import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
33import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
Wale Ogunwalee8069dc2015-08-18 09:52:01 -070034import static com.android.server.wm.WindowManagerService.H.WALLPAPER_DRAW_PENDING_TIMEOUT;
Wale Ogunwalee8069dc2015-08-18 09:52:01 -070035
chaviw0315a1a2018-03-05 15:28:35 -080036import android.graphics.Bitmap;
chaviw0315a1a2018-03-05 15:28:35 -080037import android.graphics.Rect;
Wale Ogunwalee8069dc2015-08-18 09:52:01 -070038import android.os.Bundle;
39import android.os.Debug;
40import android.os.IBinder;
41import android.os.RemoteException;
42import android.os.SystemClock;
Wale Ogunwale0c4a40ef2016-10-07 07:06:40 -070043import android.util.ArraySet;
Wale Ogunwalee8069dc2015-08-18 09:52:01 -070044import android.util.Slog;
45import android.view.DisplayInfo;
chaviw0315a1a2018-03-05 15:28:35 -080046import android.view.SurfaceControl;
Wale Ogunwalee8069dc2015-08-18 09:52:01 -070047import android.view.WindowManager;
Jorim Jaggife762342016-10-13 14:33:27 +020048import android.view.animation.Animation;
Wale Ogunwalee8069dc2015-08-18 09:52:01 -070049
Vishnu Naire6e2b0f2019-02-21 10:41:00 -080050import com.android.internal.annotations.VisibleForTesting;
lumark588a3e82018-07-20 18:53:54 +080051import com.android.internal.util.ToBooleanFunction;
52
Wale Ogunwalee8069dc2015-08-18 09:52:01 -070053import java.io.PrintWriter;
54import java.util.ArrayList;
55
56/**
57 * Controls wallpaper windows visibility, ordering, and so on.
58 * NOTE: All methods in this class must be called with the window manager service lock held.
59 */
60class WallpaperController {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -080061 private static final String TAG = TAG_WITH_CLASS_NAME ? "WallpaperController" : TAG_WM;
Wale Ogunwale1e129a42016-11-21 13:03:47 -080062 private WindowManagerService mService;
wilsonshihc32538e2018-11-07 17:27:34 +080063 private final DisplayContent mDisplayContent;
Wale Ogunwalee8069dc2015-08-18 09:52:01 -070064
Jorim Jaggi879ff722016-11-04 18:08:17 -070065 private final ArrayList<WallpaperWindowToken> mWallpaperTokens = new ArrayList<>();
Wale Ogunwalee8069dc2015-08-18 09:52:01 -070066
67 // If non-null, this is the currently visible window that is associated
68 // with the wallpaper.
69 private WindowState mWallpaperTarget = null;
70 // If non-null, we are in the middle of animating from one wallpaper target
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -080071 // to another, and this is the previous wallpaper target.
72 private WindowState mPrevWallpaperTarget = null;
Wale Ogunwalee8069dc2015-08-18 09:52:01 -070073
Wale Ogunwalee8069dc2015-08-18 09:52:01 -070074 private float mLastWallpaperX = -1;
75 private float mLastWallpaperY = -1;
76 private float mLastWallpaperXStep = -1;
77 private float mLastWallpaperYStep = -1;
78 private int mLastWallpaperDisplayOffsetX = Integer.MIN_VALUE;
79 private int mLastWallpaperDisplayOffsetY = Integer.MIN_VALUE;
80
81 // This is set when we are waiting for a wallpaper to tell us it is done
82 // changing its scroll position.
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -080083 private WindowState mWaitingOnWallpaper;
Wale Ogunwalee8069dc2015-08-18 09:52:01 -070084
85 // The last time we had a timeout when waiting for a wallpaper.
86 private long mLastWallpaperTimeoutTime;
87 // We give a wallpaper up to 150ms to finish scrolling.
88 private static final long WALLPAPER_TIMEOUT = 150;
89 // Time we wait after a timeout before trying to wait again.
90 private static final long WALLPAPER_TIMEOUT_RECOVERY = 10000;
91
92 // Set to the wallpaper window we would like to hide once the transition animations are done.
93 // This is useful in cases where we don't want the wallpaper to be hidden when the close app
94 // is a wallpaper target and is done animating out, but the opening app isn't a wallpaper
95 // target and isn't done animating in.
Wale Ogunwalee4da0c12016-07-29 12:47:02 -070096 WindowState mDeferredHideWallpaper = null;
Wale Ogunwalee8069dc2015-08-18 09:52:01 -070097
98 // We give a wallpaper up to 500ms to finish drawing before playing app transitions.
99 private static final long WALLPAPER_DRAW_PENDING_TIMEOUT_DURATION = 500;
100 private static final int WALLPAPER_DRAW_NORMAL = 0;
101 private static final int WALLPAPER_DRAW_PENDING = 1;
102 private static final int WALLPAPER_DRAW_TIMEOUT = 2;
103 private int mWallpaperDrawState = WALLPAPER_DRAW_NORMAL;
104
chaviw0315a1a2018-03-05 15:28:35 -0800105 /**
106 * Temporary storage for taking a screenshot of the wallpaper.
107 * @see #screenshotWallpaperLocked()
108 */
109 private WindowState mTmpTopWallpaper;
110
Wale Ogunwale5f61d042015-08-20 10:09:47 -0700111 private final FindWallpaperTargetResult mFindResults = new FindWallpaperTargetResult();
112
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800113 private final ToBooleanFunction<WindowState> mFindWallpaperTargetFunction = w -> {
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800114 if ((w.mAttrs.type == TYPE_WALLPAPER)) {
115 if (mFindResults.topWallpaper == null || mFindResults.resetTopWallpaper) {
116 mFindResults.setTopWallpaper(w);
117 mFindResults.resetTopWallpaper = false;
118 }
119 return false;
120 }
121
122 mFindResults.resetTopWallpaper = true;
Issei Suzukif2f6c912019-11-08 11:24:18 +0100123 if (w.mActivityRecord != null && !w.mActivityRecord.isVisible()
lumark9bca6b42019-10-17 18:35:22 +0800124 && !w.mActivityRecord.isAnimating(TRANSITION)) {
Jorim Jaggi8f520872018-08-14 17:00:20 +0200125
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800126 // If this window's app token is hidden and not animating, it is of no interest to us.
Jorim Jaggi8f520872018-08-14 17:00:20 +0200127 if (DEBUG_WALLPAPER) Slog.v(TAG, "Skipping hidden and not animating token: " + w);
128 return false;
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800129 }
130 if (DEBUG_WALLPAPER) Slog.v(TAG, "Win " + w + ": isOnScreen=" + w.isOnScreen()
131 + " mDrawState=" + w.mWinAnimator.mDrawState);
132
133 if (w.mWillReplaceWindow && mWallpaperTarget == null
134 && !mFindResults.useTopWallpaperAsTarget) {
135 // When we are replacing a window and there was wallpaper before replacement, we want to
136 // keep the window until the new windows fully appear and can determine the visibility,
137 // to avoid flickering.
138 mFindResults.setUseTopWallpaperAsTarget(true);
139 }
140
Garfield Tane8d84ab2019-10-11 09:49:40 -0700141 final boolean keyguardGoingAwayWithWallpaper = (w.mActivityRecord != null
lumark9bca6b42019-10-17 18:35:22 +0800142 && w.mActivityRecord.isAnimating(TRANSITION)
Garfield Tane8d84ab2019-10-11 09:49:40 -0700143 && AppTransition.isKeyguardGoingAwayTransit(w.mActivityRecord.getTransit())
144 && (w.mActivityRecord.getTransitFlags()
Jorim Jaggif5f9e122017-10-24 18:21:09 +0200145 & TRANSIT_FLAG_KEYGUARD_GOING_AWAY_WITH_WALLPAPER) != 0);
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800146
147 boolean needsShowWhenLockedWallpaper = false;
148 if ((w.mAttrs.flags & FLAG_SHOW_WHEN_LOCKED) != 0
149 && mService.mPolicy.isKeyguardLocked()
150 && mService.mPolicy.isKeyguardOccluded()) {
151 // The lowest show when locked window decides whether we need to put the wallpaper
152 // behind.
153 needsShowWhenLockedWallpaper = !isFullscreen(w.mAttrs)
Garfield Tane8d84ab2019-10-11 09:49:40 -0700154 || (w.mActivityRecord != null && !w.mActivityRecord.fillsParent());
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800155 }
156
157 if (keyguardGoingAwayWithWallpaper || needsShowWhenLockedWallpaper) {
158 // Keep the wallpaper during Keyguard exit but also when it's needed for a
159 // non-fullscreen show when locked activity.
160 mFindResults.setUseTopWallpaperAsTarget(true);
161 }
162
Winson Chunge2d72172018-01-25 17:46:20 +0000163 final RecentsAnimationController recentsAnimationController =
164 mService.getRecentsAnimationController();
lumark19a5d2e2019-10-11 16:19:30 +0800165 final boolean animationWallpaper = w.mActivityRecord != null
166 && w.mActivityRecord.getAnimation() != null
Garfield Tane8d84ab2019-10-11 09:49:40 -0700167 && w.mActivityRecord.getAnimation().getShowWallpaper();
Jorim Jaggi82c17862018-02-21 17:50:18 +0100168 final boolean hasWallpaper = (w.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0
169 || animationWallpaper;
Winson Chunge2d72172018-01-25 17:46:20 +0000170 final boolean isRecentsTransitionTarget = (recentsAnimationController != null
171 && recentsAnimationController.isWallpaperVisible(w));
172 if (isRecentsTransitionTarget) {
173 if (DEBUG_WALLPAPER) Slog.v(TAG, "Found recents animation wallpaper target: " + w);
174 mFindResults.setWallpaperTarget(w);
175 return true;
176 } else if (hasWallpaper && w.isOnScreen()
177 && (mWallpaperTarget == w || w.isDrawFinishedLw())) {
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800178 if (DEBUG_WALLPAPER) Slog.v(TAG, "Found wallpaper target: " + w);
179 mFindResults.setWallpaperTarget(w);
lumark9bca6b42019-10-17 18:35:22 +0800180 if (w == mWallpaperTarget && w.isAnimating(TRANSITION | PARENTS)) {
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800181 // The current wallpaper target is animating, so we'll look behind it for
182 // another possible target and figure out what is going on later.
183 if (DEBUG_WALLPAPER) Slog.v(TAG,
184 "Win " + w + ": token animating, looking behind.");
185 }
186 // Found a target! End search.
187 return true;
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800188 }
189 return false;
190 };
191
wilsonshihc32538e2018-11-07 17:27:34 +0800192 WallpaperController(WindowManagerService service, DisplayContent displayContent) {
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700193 mService = service;
wilsonshihc32538e2018-11-07 17:27:34 +0800194 mDisplayContent = displayContent;
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700195 }
196
197 WindowState getWallpaperTarget() {
198 return mWallpaperTarget;
199 }
200
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700201 boolean isWallpaperTarget(WindowState win) {
202 return win == mWallpaperTarget;
203 }
204
205 boolean isBelowWallpaperTarget(WindowState win) {
206 return mWallpaperTarget != null && mWallpaperTarget.mLayer >= win.mBaseLayer;
207 }
208
209 boolean isWallpaperVisible() {
210 return isWallpaperVisible(mWallpaperTarget);
211 }
212
Jorim Jaggife762342016-10-13 14:33:27 +0200213 /**
214 * Starts {@param a} on all wallpaper windows.
215 */
216 void startWallpaperAnimation(Animation a) {
217 for (int curTokenNdx = mWallpaperTokens.size() - 1; curTokenNdx >= 0; curTokenNdx--) {
Jorim Jaggi879ff722016-11-04 18:08:17 -0700218 final WallpaperWindowToken token = mWallpaperTokens.get(curTokenNdx);
Jorim Jaggife762342016-10-13 14:33:27 +0200219 token.startAnimation(a);
220 }
221 }
222
Winson Chunge2d72172018-01-25 17:46:20 +0000223 private final boolean isWallpaperVisible(WindowState wallpaperTarget) {
224 final RecentsAnimationController recentsAnimationController =
225 mService.getRecentsAnimationController();
226 boolean isAnimatingWithRecentsComponent = recentsAnimationController != null
227 && recentsAnimationController.isWallpaperVisible(wallpaperTarget);
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700228 if (DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper vis: target " + wallpaperTarget + ", obscured="
229 + (wallpaperTarget != null ? Boolean.toString(wallpaperTarget.mObscured) : "??")
Garfield Tane8d84ab2019-10-11 09:49:40 -0700230 + " animating=" + ((wallpaperTarget != null && wallpaperTarget.mActivityRecord != null)
lumark9bca6b42019-10-17 18:35:22 +0800231 ? wallpaperTarget.mActivityRecord.isAnimating(TRANSITION) : null)
Winson Chunge2d72172018-01-25 17:46:20 +0000232 + " prev=" + mPrevWallpaperTarget
233 + " recentsAnimationWallpaperVisible=" + isAnimatingWithRecentsComponent);
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700234 return (wallpaperTarget != null
Winson Chunge2d72172018-01-25 17:46:20 +0000235 && (!wallpaperTarget.mObscured
236 || isAnimatingWithRecentsComponent
Garfield Tane8d84ab2019-10-11 09:49:40 -0700237 || (wallpaperTarget.mActivityRecord != null
lumark9bca6b42019-10-17 18:35:22 +0800238 && wallpaperTarget.mActivityRecord.isAnimating(TRANSITION))))
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -0800239 || mPrevWallpaperTarget != null;
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700240 }
241
242 boolean isWallpaperTargetAnimating() {
lumark9bca6b42019-10-17 18:35:22 +0800243 return mWallpaperTarget != null && mWallpaperTarget.isAnimating(TRANSITION | PARENTS)
Garfield Tane8d84ab2019-10-11 09:49:40 -0700244 && (mWallpaperTarget.mActivityRecord == null
245 || !mWallpaperTarget.mActivityRecord.isWaitingForTransitionStart());
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700246 }
247
248 void updateWallpaperVisibility() {
Filip Gruszczynski63a35e22015-11-05 15:38:59 -0800249 final boolean visible = isWallpaperVisible(mWallpaperTarget);
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700250
251 for (int curTokenNdx = mWallpaperTokens.size() - 1; curTokenNdx >= 0; curTokenNdx--) {
Jorim Jaggi879ff722016-11-04 18:08:17 -0700252 final WallpaperWindowToken token = mWallpaperTokens.get(curTokenNdx);
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -0700253 token.updateWallpaperVisibility(visible);
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700254 }
255 }
256
257 void hideDeferredWallpapersIfNeeded() {
258 if (mDeferredHideWallpaper != null) {
259 hideWallpapers(mDeferredHideWallpaper);
260 mDeferredHideWallpaper = null;
261 }
262 }
263
264 void hideWallpapers(final WindowState winGoingAway) {
265 if (mWallpaperTarget != null
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -0800266 && (mWallpaperTarget != winGoingAway || mPrevWallpaperTarget != null)) {
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700267 return;
268 }
lumark588a3e82018-07-20 18:53:54 +0800269 if (mWallpaperTarget != null
270 && mWallpaperTarget.getDisplayContent().mAppTransition.isRunning()) {
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700271 // Defer hiding the wallpaper when app transition is running until the animations
272 // are done.
273 mDeferredHideWallpaper = winGoingAway;
274 return;
275 }
276
277 final boolean wasDeferred = (mDeferredHideWallpaper == winGoingAway);
278 for (int i = mWallpaperTokens.size() - 1; i >= 0; i--) {
Jorim Jaggi879ff722016-11-04 18:08:17 -0700279 final WallpaperWindowToken token = mWallpaperTokens.get(i);
Wale Ogunwalee4da0c12016-07-29 12:47:02 -0700280 token.hideWallpaperToken(wasDeferred, "hideWallpapers");
Issei Suzukif2f6c912019-11-08 11:24:18 +0100281 if (DEBUG_WALLPAPER_LIGHT && token.isVisible()) {
282 Slog.d(TAG, "Hiding wallpaper " + token
283 + " from " + winGoingAway + " target=" + mWallpaperTarget + " prev="
284 + mPrevWallpaperTarget + "\n" + Debug.getCallers(5, " "));
285 }
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700286 }
287 }
288
289 boolean updateWallpaperOffset(WindowState wallpaperWin, int dw, int dh, boolean sync) {
Robert Carr217e7cc2018-01-31 18:08:39 -0800290 int xOffset = 0;
291 int yOffset = 0;
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700292 boolean rawChanged = false;
Winson4b4ba902016-07-27 19:45:52 -0700293 // Set the default wallpaper x-offset to either edge of the screen (depending on RTL), to
294 // match the behavior of most Launchers
295 float defaultWallpaperX = wallpaperWin.isRtl() ? 1f : 0f;
296 float wpx = mLastWallpaperX >= 0 ? mLastWallpaperX : defaultWallpaperX;
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700297 float wpxs = mLastWallpaperXStep >= 0 ? mLastWallpaperXStep : -1.0f;
chaviw492139a2018-07-16 16:07:35 -0700298 int availw = wallpaperWin.getFrameLw().right - wallpaperWin.getFrameLw().left - dw;
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700299 int offset = availw > 0 ? -(int)(availw * wpx + .5f) : 0;
300 if (mLastWallpaperDisplayOffsetX != Integer.MIN_VALUE) {
301 offset += mLastWallpaperDisplayOffsetX;
302 }
Robert Carr217e7cc2018-01-31 18:08:39 -0800303 xOffset = offset;
304
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700305 if (wallpaperWin.mWallpaperX != wpx || wallpaperWin.mWallpaperXStep != wpxs) {
306 wallpaperWin.mWallpaperX = wpx;
307 wallpaperWin.mWallpaperXStep = wpxs;
308 rawChanged = true;
309 }
310
311 float wpy = mLastWallpaperY >= 0 ? mLastWallpaperY : 0.5f;
312 float wpys = mLastWallpaperYStep >= 0 ? mLastWallpaperYStep : -1.0f;
chaviw492139a2018-07-16 16:07:35 -0700313 int availh = wallpaperWin.getFrameLw().bottom - wallpaperWin.getFrameLw().top - dh;
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700314 offset = availh > 0 ? -(int)(availh * wpy + .5f) : 0;
315 if (mLastWallpaperDisplayOffsetY != Integer.MIN_VALUE) {
316 offset += mLastWallpaperDisplayOffsetY;
317 }
Robert Carr217e7cc2018-01-31 18:08:39 -0800318 yOffset = offset;
319
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700320 if (wallpaperWin.mWallpaperY != wpy || wallpaperWin.mWallpaperYStep != wpys) {
321 wallpaperWin.mWallpaperY = wpy;
322 wallpaperWin.mWallpaperYStep = wpys;
323 rawChanged = true;
324 }
325
Robert Carr217e7cc2018-01-31 18:08:39 -0800326 boolean changed = wallpaperWin.mWinAnimator.setWallpaperOffset(xOffset, yOffset);
327
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700328 if (rawChanged && (wallpaperWin.mAttrs.privateFlags &
329 WindowManager.LayoutParams.PRIVATE_FLAG_WANTS_OFFSET_NOTIFICATIONS) != 0) {
330 try {
331 if (DEBUG_WALLPAPER) Slog.v(TAG, "Report new wp offset "
332 + wallpaperWin + " x=" + wallpaperWin.mWallpaperX
333 + " y=" + wallpaperWin.mWallpaperY);
334 if (sync) {
335 mWaitingOnWallpaper = wallpaperWin;
336 }
337 wallpaperWin.mClient.dispatchWallpaperOffsets(
338 wallpaperWin.mWallpaperX, wallpaperWin.mWallpaperY,
339 wallpaperWin.mWallpaperXStep, wallpaperWin.mWallpaperYStep, sync);
340 if (sync) {
341 if (mWaitingOnWallpaper != null) {
342 long start = SystemClock.uptimeMillis();
343 if ((mLastWallpaperTimeoutTime + WALLPAPER_TIMEOUT_RECOVERY)
344 < start) {
345 try {
346 if (DEBUG_WALLPAPER) Slog.v(TAG,
347 "Waiting for offset complete...");
Wale Ogunwaledb485de2018-10-29 09:47:07 -0700348 mService.mGlobalLock.wait(WALLPAPER_TIMEOUT);
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700349 } catch (InterruptedException e) {
350 }
351 if (DEBUG_WALLPAPER) Slog.v(TAG, "Offset complete!");
352 if ((start + WALLPAPER_TIMEOUT) < SystemClock.uptimeMillis()) {
353 Slog.i(TAG, "Timeout waiting for wallpaper to offset: "
354 + wallpaperWin);
355 mLastWallpaperTimeoutTime = start;
356 }
357 }
358 mWaitingOnWallpaper = null;
359 }
360 }
361 } catch (RemoteException e) {
362 }
363 }
364
365 return changed;
366 }
367
368 void setWindowWallpaperPosition(
369 WindowState window, float x, float y, float xStep, float yStep) {
370 if (window.mWallpaperX != x || window.mWallpaperY != y) {
371 window.mWallpaperX = x;
372 window.mWallpaperY = y;
373 window.mWallpaperXStep = xStep;
374 window.mWallpaperYStep = yStep;
375 updateWallpaperOffsetLocked(window, true);
376 }
377 }
378
379 void setWindowWallpaperDisplayOffset(WindowState window, int x, int y) {
380 if (window.mWallpaperDisplayOffsetX != x || window.mWallpaperDisplayOffsetY != y) {
381 window.mWallpaperDisplayOffsetX = x;
382 window.mWallpaperDisplayOffsetY = y;
383 updateWallpaperOffsetLocked(window, true);
384 }
385 }
386
387 Bundle sendWindowWallpaperCommand(
388 WindowState window, String action, int x, int y, int z, Bundle extras, boolean sync) {
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -0800389 if (window == mWallpaperTarget || window == mPrevWallpaperTarget) {
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700390 boolean doWait = sync;
391 for (int curTokenNdx = mWallpaperTokens.size() - 1; curTokenNdx >= 0; curTokenNdx--) {
Jorim Jaggi879ff722016-11-04 18:08:17 -0700392 final WallpaperWindowToken token = mWallpaperTokens.get(curTokenNdx);
Wale Ogunwalee4da0c12016-07-29 12:47:02 -0700393 token.sendWindowWallpaperCommand(action, x, y, z, extras, sync);
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700394 }
395
396 if (doWait) {
397 // TODO: Need to wait for result.
398 }
399 }
400
401 return null;
402 }
403
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -0700404 private void updateWallpaperOffsetLocked(WindowState changingTarget, boolean sync) {
wilsonshihc32538e2018-11-07 17:27:34 +0800405 final DisplayInfo displayInfo = mDisplayContent.getDisplayInfo();
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700406 final int dw = displayInfo.logicalWidth;
407 final int dh = displayInfo.logicalHeight;
408
409 WindowState target = mWallpaperTarget;
410 if (target != null) {
411 if (target.mWallpaperX >= 0) {
412 mLastWallpaperX = target.mWallpaperX;
413 } else if (changingTarget.mWallpaperX >= 0) {
414 mLastWallpaperX = changingTarget.mWallpaperX;
415 }
416 if (target.mWallpaperY >= 0) {
417 mLastWallpaperY = target.mWallpaperY;
418 } else if (changingTarget.mWallpaperY >= 0) {
419 mLastWallpaperY = changingTarget.mWallpaperY;
420 }
421 if (target.mWallpaperDisplayOffsetX != Integer.MIN_VALUE) {
422 mLastWallpaperDisplayOffsetX = target.mWallpaperDisplayOffsetX;
423 } else if (changingTarget.mWallpaperDisplayOffsetX != Integer.MIN_VALUE) {
424 mLastWallpaperDisplayOffsetX = changingTarget.mWallpaperDisplayOffsetX;
425 }
426 if (target.mWallpaperDisplayOffsetY != Integer.MIN_VALUE) {
427 mLastWallpaperDisplayOffsetY = target.mWallpaperDisplayOffsetY;
428 } else if (changingTarget.mWallpaperDisplayOffsetY != Integer.MIN_VALUE) {
429 mLastWallpaperDisplayOffsetY = changingTarget.mWallpaperDisplayOffsetY;
430 }
431 if (target.mWallpaperXStep >= 0) {
432 mLastWallpaperXStep = target.mWallpaperXStep;
433 } else if (changingTarget.mWallpaperXStep >= 0) {
434 mLastWallpaperXStep = changingTarget.mWallpaperXStep;
435 }
436 if (target.mWallpaperYStep >= 0) {
437 mLastWallpaperYStep = target.mWallpaperYStep;
438 } else if (changingTarget.mWallpaperYStep >= 0) {
439 mLastWallpaperYStep = changingTarget.mWallpaperYStep;
440 }
441 }
442
443 for (int curTokenNdx = mWallpaperTokens.size() - 1; curTokenNdx >= 0; curTokenNdx--) {
Wale Ogunwalee4da0c12016-07-29 12:47:02 -0700444 mWallpaperTokens.get(curTokenNdx).updateWallpaperOffset(dw, dh, sync);
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700445 }
446 }
447
448 void clearLastWallpaperTimeoutTime() {
449 mLastWallpaperTimeoutTime = 0;
450 }
451
452 void wallpaperCommandComplete(IBinder window) {
453 if (mWaitingOnWallpaper != null &&
454 mWaitingOnWallpaper.mClient.asBinder() == window) {
455 mWaitingOnWallpaper = null;
Wale Ogunwaledb485de2018-10-29 09:47:07 -0700456 mService.mGlobalLock.notifyAll();
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700457 }
458 }
459
460 void wallpaperOffsetsComplete(IBinder window) {
461 if (mWaitingOnWallpaper != null &&
462 mWaitingOnWallpaper.mClient.asBinder() == window) {
463 mWaitingOnWallpaper = null;
Wale Ogunwaledb485de2018-10-29 09:47:07 -0700464 mService.mGlobalLock.notifyAll();
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700465 }
466 }
467
wilsonshihc32538e2018-11-07 17:27:34 +0800468 private void findWallpaperTarget() {
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800469 mFindResults.reset();
wilsonshihc32538e2018-11-07 17:27:34 +0800470 if (mDisplayContent.isStackVisible(WINDOWING_MODE_FREEFORM)) {
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -0800471 // In freeform mode we set the wallpaper as its own target, so we don't need an
472 // additional window to make it visible.
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800473 mFindResults.setUseTopWallpaperAsTarget(true);
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -0800474 }
Wale Ogunwale6cbba702016-06-28 16:27:31 -0700475
wilsonshihc32538e2018-11-07 17:27:34 +0800476 mDisplayContent.forAllWindows(mFindWallpaperTargetFunction, true /* traverseTopToBottom */);
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -0800477
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800478 if (mFindResults.wallpaperTarget == null && mFindResults.useTopWallpaperAsTarget) {
479 mFindResults.setWallpaperTarget(mFindResults.topWallpaper);
Wale Ogunwale21fdd912015-08-20 12:34:57 -0700480 }
Wale Ogunwale5f61d042015-08-20 10:09:47 -0700481 }
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700482
Jorim Jaggife762342016-10-13 14:33:27 +0200483 private boolean isFullscreen(WindowManager.LayoutParams attrs) {
484 return attrs.x == 0 && attrs.y == 0
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -0800485 && attrs.width == MATCH_PARENT && attrs.height == MATCH_PARENT;
Jorim Jaggife762342016-10-13 14:33:27 +0200486 }
487
Wale Ogunwale0c4a40ef2016-10-07 07:06:40 -0700488 /** Updates the target wallpaper if needed and returns true if an update happened. */
wilsonshihc32538e2018-11-07 17:27:34 +0800489 private void updateWallpaperWindowsTarget(FindWallpaperTargetResult result) {
Wale Ogunwale5f61d042015-08-20 10:09:47 -0700490
Wale Ogunwale5f61d042015-08-20 10:09:47 -0700491 WindowState wallpaperTarget = result.wallpaperTarget;
Wale Ogunwale5f61d042015-08-20 10:09:47 -0700492
Wale Ogunwale0c4a40ef2016-10-07 07:06:40 -0700493 if (mWallpaperTarget == wallpaperTarget
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -0800494 || (mPrevWallpaperTarget != null && mPrevWallpaperTarget == wallpaperTarget)) {
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700495
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -0800496 if (mPrevWallpaperTarget == null) {
497 return;
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700498 }
499
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -0800500 // Is it time to stop animating?
501 if (!mPrevWallpaperTarget.isAnimatingLw()) {
502 if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG, "No longer animating wallpaper targets!");
503 mPrevWallpaperTarget = null;
504 mWallpaperTarget = wallpaperTarget;
505 }
506 return;
Wale Ogunwale0c4a40ef2016-10-07 07:06:40 -0700507 }
508
509 if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -0800510 "New wallpaper target: " + wallpaperTarget + " prevTarget: " + mWallpaperTarget);
Wale Ogunwale0c4a40ef2016-10-07 07:06:40 -0700511
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -0800512 mPrevWallpaperTarget = null;
Wale Ogunwale0c4a40ef2016-10-07 07:06:40 -0700513
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -0800514 final WindowState prevWallpaperTarget = mWallpaperTarget;
Wale Ogunwale0c4a40ef2016-10-07 07:06:40 -0700515 mWallpaperTarget = wallpaperTarget;
516
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -0800517 if (wallpaperTarget == null || prevWallpaperTarget == null) {
518 return;
Wale Ogunwale0c4a40ef2016-10-07 07:06:40 -0700519 }
520
521 // Now what is happening... if the current and new targets are animating,
522 // then we are in our super special mode!
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -0800523 boolean oldAnim = prevWallpaperTarget.isAnimatingLw();
Wale Ogunwale0c4a40ef2016-10-07 07:06:40 -0700524 boolean foundAnim = wallpaperTarget.isAnimatingLw();
525 if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
526 "New animation: " + foundAnim + " old animation: " + oldAnim);
527
528 if (!foundAnim || !oldAnim) {
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -0800529 return;
Wale Ogunwale0c4a40ef2016-10-07 07:06:40 -0700530 }
531
wilsonshihc32538e2018-11-07 17:27:34 +0800532 if (mDisplayContent.getWindow(w -> w == prevWallpaperTarget) == null) {
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -0800533 return;
Wale Ogunwale0c4a40ef2016-10-07 07:06:40 -0700534 }
535
Garfield Tane8d84ab2019-10-11 09:49:40 -0700536 final boolean newTargetHidden = wallpaperTarget.mActivityRecord != null
Issei Suzuki1669ea42019-11-06 14:20:59 +0100537 && !wallpaperTarget.mActivityRecord.mVisibleRequested;
Garfield Tane8d84ab2019-10-11 09:49:40 -0700538 final boolean oldTargetHidden = prevWallpaperTarget.mActivityRecord != null
Issei Suzuki1669ea42019-11-06 14:20:59 +0100539 && !prevWallpaperTarget.mActivityRecord.mVisibleRequested;
Wale Ogunwale0c4a40ef2016-10-07 07:06:40 -0700540
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -0800541 if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG, "Animating wallpapers:" + " old: "
542 + prevWallpaperTarget + " hidden=" + oldTargetHidden + " new: " + wallpaperTarget
543 + " hidden=" + newTargetHidden);
Wale Ogunwale0c4a40ef2016-10-07 07:06:40 -0700544
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -0800545 mPrevWallpaperTarget = prevWallpaperTarget;
Wale Ogunwale0c4a40ef2016-10-07 07:06:40 -0700546
547 if (newTargetHidden && !oldTargetHidden) {
548 if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG, "Old wallpaper still the target.");
549 // Use the old target if new target is hidden but old target
550 // is not. If they're both hidden, still use the new target.
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -0800551 mWallpaperTarget = prevWallpaperTarget;
Wale Ogunwale0c4a40ef2016-10-07 07:06:40 -0700552 } else if (newTargetHidden == oldTargetHidden
Garfield Tane8d84ab2019-10-11 09:49:40 -0700553 && !mDisplayContent.mOpeningApps.contains(wallpaperTarget.mActivityRecord)
554 && (mDisplayContent.mOpeningApps.contains(prevWallpaperTarget.mActivityRecord)
555 || mDisplayContent.mClosingApps.contains(prevWallpaperTarget.mActivityRecord))) {
Wale Ogunwale0c4a40ef2016-10-07 07:06:40 -0700556 // If they're both hidden (or both not hidden), prefer the one that's currently in
557 // opening or closing app list, this allows transition selection logic to better
558 // determine the wallpaper status of opening/closing apps.
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -0800559 mWallpaperTarget = prevWallpaperTarget;
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700560 }
561
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -0800562 result.setWallpaperTarget(wallpaperTarget);
Wale Ogunwale5f61d042015-08-20 10:09:47 -0700563 }
564
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -0800565 private void updateWallpaperTokens(boolean visible) {
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700566 for (int curTokenNdx = mWallpaperTokens.size() - 1; curTokenNdx >= 0; curTokenNdx--) {
Jorim Jaggi879ff722016-11-04 18:08:17 -0700567 final WallpaperWindowToken token = mWallpaperTokens.get(curTokenNdx);
Jorim Jaggib0fc8172017-11-23 17:04:08 +0000568 token.updateWallpaperWindows(visible);
Robert Carrdee1b3f2017-02-27 11:33:33 -0800569 token.getDisplayContent().assignWindowLayers(false);
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700570 }
Wale Ogunwale5f61d042015-08-20 10:09:47 -0700571 }
572
wilsonshihc32538e2018-11-07 17:27:34 +0800573 void adjustWallpaperWindows() {
574 mDisplayContent.mWallpaperMayChange = false;
Wale Ogunwale5f61d042015-08-20 10:09:47 -0700575
Wale Ogunwale5f61d042015-08-20 10:09:47 -0700576 // First find top-most window that has asked to be on top of the wallpaper;
577 // all wallpapers go behind it.
wilsonshihc32538e2018-11-07 17:27:34 +0800578 findWallpaperTarget();
579 updateWallpaperWindowsTarget(mFindResults);
Wale Ogunwale5f61d042015-08-20 10:09:47 -0700580
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -0800581 // The window is visible to the compositor...but is it visible to the user?
582 // That is what the wallpaper cares about.
583 final boolean visible = mWallpaperTarget != null && isWallpaperVisible(mWallpaperTarget);
wilsonshihc32538e2018-11-07 17:27:34 +0800584 if (DEBUG_WALLPAPER) {
585 Slog.v(TAG, "Wallpaper visibility: " + visible + " at display "
586 + mDisplayContent.getDisplayId());
587 }
Wale Ogunwale5f61d042015-08-20 10:09:47 -0700588
589 if (visible) {
590 if (mWallpaperTarget.mWallpaperX >= 0) {
591 mLastWallpaperX = mWallpaperTarget.mWallpaperX;
592 mLastWallpaperXStep = mWallpaperTarget.mWallpaperXStep;
593 }
594 if (mWallpaperTarget.mWallpaperY >= 0) {
595 mLastWallpaperY = mWallpaperTarget.mWallpaperY;
596 mLastWallpaperYStep = mWallpaperTarget.mWallpaperYStep;
597 }
598 if (mWallpaperTarget.mWallpaperDisplayOffsetX != Integer.MIN_VALUE) {
599 mLastWallpaperDisplayOffsetX = mWallpaperTarget.mWallpaperDisplayOffsetX;
600 }
601 if (mWallpaperTarget.mWallpaperDisplayOffsetY != Integer.MIN_VALUE) {
602 mLastWallpaperDisplayOffsetY = mWallpaperTarget.mWallpaperDisplayOffsetY;
603 }
604 }
605
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -0800606 updateWallpaperTokens(visible);
Wale Ogunwale5f61d042015-08-20 10:09:47 -0700607
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -0800608 if (DEBUG_WALLPAPER_LIGHT) Slog.d(TAG, "New wallpaper: target=" + mWallpaperTarget
609 + " prev=" + mPrevWallpaperTarget);
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700610 }
611
612 boolean processWallpaperDrawPendingTimeout() {
613 if (mWallpaperDrawState == WALLPAPER_DRAW_PENDING) {
614 mWallpaperDrawState = WALLPAPER_DRAW_TIMEOUT;
Adrian Roosb125e0b2019-10-02 14:55:14 +0200615 if (DEBUG_WALLPAPER) {
616 Slog.v(TAG, "*** WALLPAPER DRAW TIMEOUT");
617 }
Winson Chunge2d72172018-01-25 17:46:20 +0000618
Winson Chungfe571032019-06-18 11:22:53 -0700619 // If there was a pending recents animation, start the animation anyways (it's better
620 // to not see the wallpaper than for the animation to not start)
Winson Chunge2d72172018-01-25 17:46:20 +0000621 if (mService.getRecentsAnimationController() != null) {
Winson Chungfe571032019-06-18 11:22:53 -0700622 mService.getRecentsAnimationController().startAnimation();
Winson Chunge2d72172018-01-25 17:46:20 +0000623 }
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700624 return true;
625 }
626 return false;
627 }
628
629 boolean wallpaperTransitionReady() {
630 boolean transitionReady = true;
631 boolean wallpaperReady = true;
632 for (int curTokenIndex = mWallpaperTokens.size() - 1;
633 curTokenIndex >= 0 && wallpaperReady; curTokenIndex--) {
Jorim Jaggi879ff722016-11-04 18:08:17 -0700634 final WallpaperWindowToken token = mWallpaperTokens.get(curTokenIndex);
Wale Ogunwalee4da0c12016-07-29 12:47:02 -0700635 if (token.hasVisibleNotDrawnWallpaper()) {
636 // We've told this wallpaper to be visible, but it is not drawn yet
637 wallpaperReady = false;
638 if (mWallpaperDrawState != WALLPAPER_DRAW_TIMEOUT) {
639 // wait for this wallpaper until it is drawn or timeout
640 transitionReady = false;
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700641 }
Wale Ogunwalee4da0c12016-07-29 12:47:02 -0700642 if (mWallpaperDrawState == WALLPAPER_DRAW_NORMAL) {
643 mWallpaperDrawState = WALLPAPER_DRAW_PENDING;
wilsonshihc32538e2018-11-07 17:27:34 +0800644 mService.mH.removeMessages(WALLPAPER_DRAW_PENDING_TIMEOUT, this);
645 mService.mH.sendMessageDelayed(
646 mService.mH.obtainMessage(WALLPAPER_DRAW_PENDING_TIMEOUT, this),
647 WALLPAPER_DRAW_PENDING_TIMEOUT_DURATION);
648
Wale Ogunwalee4da0c12016-07-29 12:47:02 -0700649 }
Adrian Roosb125e0b2019-10-02 14:55:14 +0200650 if (DEBUG_WALLPAPER) {
651 Slog.v(TAG,
652 "Wallpaper should be visible but has not been drawn yet. "
653 + "mWallpaperDrawState=" + mWallpaperDrawState);
654 }
Wale Ogunwalee4da0c12016-07-29 12:47:02 -0700655 break;
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700656 }
657 }
658 if (wallpaperReady) {
659 mWallpaperDrawState = WALLPAPER_DRAW_NORMAL;
wilsonshihc32538e2018-11-07 17:27:34 +0800660 mService.mH.removeMessages(WALLPAPER_DRAW_PENDING_TIMEOUT, this);
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700661 }
662
663 return transitionReady;
664 }
665
Wale Ogunwale0c4a40ef2016-10-07 07:06:40 -0700666 /**
667 * Adjusts the wallpaper windows if the input display has a pending wallpaper layout or one of
668 * the opening apps should be a wallpaper target.
669 */
Garfield Tane8d84ab2019-10-11 09:49:40 -0700670 void adjustWallpaperWindowsForAppTransitionIfNeeded(ArraySet<ActivityRecord> openingApps,
671 ArraySet<ActivityRecord> changingApps) {
Wale Ogunwale0c4a40ef2016-10-07 07:06:40 -0700672 boolean adjust = false;
wilsonshihc32538e2018-11-07 17:27:34 +0800673 if ((mDisplayContent.pendingLayoutChanges & FINISH_LAYOUT_REDO_WALLPAPER) != 0) {
Wale Ogunwale0c4a40ef2016-10-07 07:06:40 -0700674 adjust = true;
675 } else {
676 for (int i = openingApps.size() - 1; i >= 0; --i) {
Garfield Tane8d84ab2019-10-11 09:49:40 -0700677 final ActivityRecord activity = openingApps.valueAt(i);
678 if (activity.windowsCanBeWallpaperTarget()) {
Wale Ogunwale0c4a40ef2016-10-07 07:06:40 -0700679 adjust = true;
680 break;
681 }
682 }
Evan Rosky2289ba12018-11-19 18:28:18 -0800683 if (!adjust) {
684 for (int i = changingApps.size() - 1; i >= 0; --i) {
Garfield Tane8d84ab2019-10-11 09:49:40 -0700685 final ActivityRecord activity = changingApps.valueAt(i);
686 if (activity.windowsCanBeWallpaperTarget()) {
Evan Rosky2289ba12018-11-19 18:28:18 -0800687 adjust = true;
688 break;
689 }
690 }
691 }
Wale Ogunwale0c4a40ef2016-10-07 07:06:40 -0700692 }
693
Wale Ogunwale0303c572016-10-20 10:16:29 -0700694 if (adjust) {
wilsonshihc32538e2018-11-07 17:27:34 +0800695 adjustWallpaperWindows();
Wale Ogunwale0c4a40ef2016-10-07 07:06:40 -0700696 }
697 }
698
Jorim Jaggi879ff722016-11-04 18:08:17 -0700699 void addWallpaperToken(WallpaperWindowToken token) {
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700700 mWallpaperTokens.add(token);
701 }
702
Jorim Jaggi879ff722016-11-04 18:08:17 -0700703 void removeWallpaperToken(WallpaperWindowToken token) {
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700704 mWallpaperTokens.remove(token);
705 }
706
Vishnu Naire6e2b0f2019-02-21 10:41:00 -0800707
708 @VisibleForTesting
709 boolean canScreenshotWallpaper() {
710 return canScreenshotWallpaper(getTopVisibleWallpaper());
711 }
712
713 private boolean canScreenshotWallpaper(WindowState wallpaperWindowState) {
714 if (!mService.mPolicy.isScreenOn()) {
715 if (DEBUG_SCREENSHOT) {
716 Slog.i(TAG_WM, "Attempted to take screenshot while display was off.");
717 }
718 return false;
719 }
720
721 if (wallpaperWindowState == null) {
722 if (DEBUG_SCREENSHOT) {
723 Slog.i(TAG_WM, "No visible wallpaper to screenshot");
724 }
725 return false;
726 }
727 return true;
728 }
729
chaviw0315a1a2018-03-05 15:28:35 -0800730 /**
731 * Take a screenshot of the wallpaper if it's visible.
732 *
733 * @return Bitmap of the wallpaper
734 */
735 Bitmap screenshotWallpaperLocked() {
chaviw0315a1a2018-03-05 15:28:35 -0800736 final WindowState wallpaperWindowState = getTopVisibleWallpaper();
Vishnu Naire6e2b0f2019-02-21 10:41:00 -0800737 if (!canScreenshotWallpaper(wallpaperWindowState)) {
chaviw0315a1a2018-03-05 15:28:35 -0800738 return null;
739 }
740
741 final Rect bounds = wallpaperWindowState.getBounds();
742 bounds.offsetTo(0, 0);
743
Peiyong Line3e5efd2019-03-21 20:59:47 +0000744 SurfaceControl.ScreenshotGraphicBuffer wallpaperBuffer = SurfaceControl.captureLayers(
Vishnu Nairbc9beab2019-06-25 17:28:58 -0700745 wallpaperWindowState.getSurfaceControl(), bounds, 1 /* frameScale */);
chaviw0315a1a2018-03-05 15:28:35 -0800746
747 if (wallpaperBuffer == null) {
748 Slog.w(TAG_WM, "Failed to screenshot wallpaper");
749 return null;
750 }
Peiyong Line3e5efd2019-03-21 20:59:47 +0000751 return Bitmap.wrapHardwareBuffer(
Sunny Goyal62915b22019-04-10 12:28:47 -0700752 wallpaperBuffer.getGraphicBuffer(), wallpaperBuffer.getColorSpace());
chaviw0315a1a2018-03-05 15:28:35 -0800753 }
754
755 private WindowState getTopVisibleWallpaper() {
756 mTmpTopWallpaper = null;
757
758 for (int curTokenNdx = mWallpaperTokens.size() - 1; curTokenNdx >= 0; curTokenNdx--) {
759 final WallpaperWindowToken token = mWallpaperTokens.get(curTokenNdx);
760 token.forAllWindows(w -> {
761 final WindowStateAnimator winAnim = w.mWinAnimator;
762 if (winAnim != null && winAnim.getShown() && winAnim.mLastAlpha > 0f) {
763 mTmpTopWallpaper = w;
764 return true;
765 }
766 return false;
767 }, true /* traverseTopToBottom */);
768 }
769
770 return mTmpTopWallpaper;
771 }
772
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700773 void dump(PrintWriter pw, String prefix) {
wilsonshihc32538e2018-11-07 17:27:34 +0800774 pw.print(prefix); pw.print("displayId="); pw.println(mDisplayContent.getDisplayId());
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700775 pw.print(prefix); pw.print("mWallpaperTarget="); pw.println(mWallpaperTarget);
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -0800776 if (mPrevWallpaperTarget != null) {
777 pw.print(prefix); pw.print("mPrevWallpaperTarget="); pw.println(mPrevWallpaperTarget);
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700778 }
779 pw.print(prefix); pw.print("mLastWallpaperX="); pw.print(mLastWallpaperX);
780 pw.print(" mLastWallpaperY="); pw.println(mLastWallpaperY);
781 if (mLastWallpaperDisplayOffsetX != Integer.MIN_VALUE
782 || mLastWallpaperDisplayOffsetY != Integer.MIN_VALUE) {
783 pw.print(prefix);
784 pw.print("mLastWallpaperDisplayOffsetX="); pw.print(mLastWallpaperDisplayOffsetX);
785 pw.print(" mLastWallpaperDisplayOffsetY="); pw.println(mLastWallpaperDisplayOffsetY);
786 }
787 }
788
Wale Ogunwale5f61d042015-08-20 10:09:47 -0700789 /** Helper class for storing the results of a wallpaper target find operation. */
790 final private static class FindWallpaperTargetResult {
Wale Ogunwale5f61d042015-08-20 10:09:47 -0700791 WindowState topWallpaper = null;
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -0800792 boolean useTopWallpaperAsTarget = false;
Wale Ogunwale5f61d042015-08-20 10:09:47 -0700793 WindowState wallpaperTarget = null;
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -0800794 boolean resetTopWallpaper = false;
Wale Ogunwale5f61d042015-08-20 10:09:47 -0700795
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -0800796 void setTopWallpaper(WindowState win) {
Wale Ogunwale5f61d042015-08-20 10:09:47 -0700797 topWallpaper = win;
Wale Ogunwale5f61d042015-08-20 10:09:47 -0700798 }
799
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -0800800 void setWallpaperTarget(WindowState win) {
Wale Ogunwale5f61d042015-08-20 10:09:47 -0700801 wallpaperTarget = win;
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -0800802 }
803
804 void setUseTopWallpaperAsTarget(boolean topWallpaperAsTarget) {
805 useTopWallpaperAsTarget = topWallpaperAsTarget;
Wale Ogunwale5f61d042015-08-20 10:09:47 -0700806 }
807
808 void reset() {
Wale Ogunwale5f61d042015-08-20 10:09:47 -0700809 topWallpaper = null;
Wale Ogunwale5f61d042015-08-20 10:09:47 -0700810 wallpaperTarget = null;
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -0800811 useTopWallpaperAsTarget = false;
812 resetTopWallpaper = false;
Wale Ogunwale5f61d042015-08-20 10:09:47 -0700813 }
814 }
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700815}