blob: ef7940368f15101726d8fa5a70f7672847c36f85 [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 Suzuki7b9e2572019-11-14 16:19:54 +0100123 if (w.mActivityRecord != null && w.mActivityRecord.isHidden()
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 Suzuki7b9e2572019-11-14 16:19:54 +0100281 if (DEBUG_WALLPAPER_LIGHT && !token.isHidden()) Slog.d(TAG, "Hiding wallpaper " + token
282 + " from " + winGoingAway + " target=" + mWallpaperTarget + " prev="
283 + mPrevWallpaperTarget + "\n" + Debug.getCallers(5, " "));
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700284 }
285 }
286
287 boolean updateWallpaperOffset(WindowState wallpaperWin, int dw, int dh, boolean sync) {
Robert Carr217e7cc2018-01-31 18:08:39 -0800288 int xOffset = 0;
289 int yOffset = 0;
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700290 boolean rawChanged = false;
Winson4b4ba902016-07-27 19:45:52 -0700291 // Set the default wallpaper x-offset to either edge of the screen (depending on RTL), to
292 // match the behavior of most Launchers
293 float defaultWallpaperX = wallpaperWin.isRtl() ? 1f : 0f;
294 float wpx = mLastWallpaperX >= 0 ? mLastWallpaperX : defaultWallpaperX;
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700295 float wpxs = mLastWallpaperXStep >= 0 ? mLastWallpaperXStep : -1.0f;
chaviw492139a2018-07-16 16:07:35 -0700296 int availw = wallpaperWin.getFrameLw().right - wallpaperWin.getFrameLw().left - dw;
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700297 int offset = availw > 0 ? -(int)(availw * wpx + .5f) : 0;
298 if (mLastWallpaperDisplayOffsetX != Integer.MIN_VALUE) {
299 offset += mLastWallpaperDisplayOffsetX;
300 }
Robert Carr217e7cc2018-01-31 18:08:39 -0800301 xOffset = offset;
302
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700303 if (wallpaperWin.mWallpaperX != wpx || wallpaperWin.mWallpaperXStep != wpxs) {
304 wallpaperWin.mWallpaperX = wpx;
305 wallpaperWin.mWallpaperXStep = wpxs;
306 rawChanged = true;
307 }
308
309 float wpy = mLastWallpaperY >= 0 ? mLastWallpaperY : 0.5f;
310 float wpys = mLastWallpaperYStep >= 0 ? mLastWallpaperYStep : -1.0f;
chaviw492139a2018-07-16 16:07:35 -0700311 int availh = wallpaperWin.getFrameLw().bottom - wallpaperWin.getFrameLw().top - dh;
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700312 offset = availh > 0 ? -(int)(availh * wpy + .5f) : 0;
313 if (mLastWallpaperDisplayOffsetY != Integer.MIN_VALUE) {
314 offset += mLastWallpaperDisplayOffsetY;
315 }
Robert Carr217e7cc2018-01-31 18:08:39 -0800316 yOffset = offset;
317
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700318 if (wallpaperWin.mWallpaperY != wpy || wallpaperWin.mWallpaperYStep != wpys) {
319 wallpaperWin.mWallpaperY = wpy;
320 wallpaperWin.mWallpaperYStep = wpys;
321 rawChanged = true;
322 }
323
Robert Carr217e7cc2018-01-31 18:08:39 -0800324 boolean changed = wallpaperWin.mWinAnimator.setWallpaperOffset(xOffset, yOffset);
325
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700326 if (rawChanged && (wallpaperWin.mAttrs.privateFlags &
327 WindowManager.LayoutParams.PRIVATE_FLAG_WANTS_OFFSET_NOTIFICATIONS) != 0) {
328 try {
329 if (DEBUG_WALLPAPER) Slog.v(TAG, "Report new wp offset "
330 + wallpaperWin + " x=" + wallpaperWin.mWallpaperX
331 + " y=" + wallpaperWin.mWallpaperY);
332 if (sync) {
333 mWaitingOnWallpaper = wallpaperWin;
334 }
335 wallpaperWin.mClient.dispatchWallpaperOffsets(
336 wallpaperWin.mWallpaperX, wallpaperWin.mWallpaperY,
337 wallpaperWin.mWallpaperXStep, wallpaperWin.mWallpaperYStep, sync);
338 if (sync) {
339 if (mWaitingOnWallpaper != null) {
340 long start = SystemClock.uptimeMillis();
341 if ((mLastWallpaperTimeoutTime + WALLPAPER_TIMEOUT_RECOVERY)
342 < start) {
343 try {
344 if (DEBUG_WALLPAPER) Slog.v(TAG,
345 "Waiting for offset complete...");
Wale Ogunwaledb485de2018-10-29 09:47:07 -0700346 mService.mGlobalLock.wait(WALLPAPER_TIMEOUT);
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700347 } catch (InterruptedException e) {
348 }
349 if (DEBUG_WALLPAPER) Slog.v(TAG, "Offset complete!");
350 if ((start + WALLPAPER_TIMEOUT) < SystemClock.uptimeMillis()) {
351 Slog.i(TAG, "Timeout waiting for wallpaper to offset: "
352 + wallpaperWin);
353 mLastWallpaperTimeoutTime = start;
354 }
355 }
356 mWaitingOnWallpaper = null;
357 }
358 }
359 } catch (RemoteException e) {
360 }
361 }
362
363 return changed;
364 }
365
366 void setWindowWallpaperPosition(
367 WindowState window, float x, float y, float xStep, float yStep) {
368 if (window.mWallpaperX != x || window.mWallpaperY != y) {
369 window.mWallpaperX = x;
370 window.mWallpaperY = y;
371 window.mWallpaperXStep = xStep;
372 window.mWallpaperYStep = yStep;
373 updateWallpaperOffsetLocked(window, true);
374 }
375 }
376
377 void setWindowWallpaperDisplayOffset(WindowState window, int x, int y) {
378 if (window.mWallpaperDisplayOffsetX != x || window.mWallpaperDisplayOffsetY != y) {
379 window.mWallpaperDisplayOffsetX = x;
380 window.mWallpaperDisplayOffsetY = y;
381 updateWallpaperOffsetLocked(window, true);
382 }
383 }
384
385 Bundle sendWindowWallpaperCommand(
386 WindowState window, String action, int x, int y, int z, Bundle extras, boolean sync) {
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -0800387 if (window == mWallpaperTarget || window == mPrevWallpaperTarget) {
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700388 boolean doWait = sync;
389 for (int curTokenNdx = mWallpaperTokens.size() - 1; curTokenNdx >= 0; curTokenNdx--) {
Jorim Jaggi879ff722016-11-04 18:08:17 -0700390 final WallpaperWindowToken token = mWallpaperTokens.get(curTokenNdx);
Wale Ogunwalee4da0c12016-07-29 12:47:02 -0700391 token.sendWindowWallpaperCommand(action, x, y, z, extras, sync);
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700392 }
393
394 if (doWait) {
395 // TODO: Need to wait for result.
396 }
397 }
398
399 return null;
400 }
401
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -0700402 private void updateWallpaperOffsetLocked(WindowState changingTarget, boolean sync) {
wilsonshihc32538e2018-11-07 17:27:34 +0800403 final DisplayInfo displayInfo = mDisplayContent.getDisplayInfo();
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700404 final int dw = displayInfo.logicalWidth;
405 final int dh = displayInfo.logicalHeight;
406
407 WindowState target = mWallpaperTarget;
408 if (target != null) {
409 if (target.mWallpaperX >= 0) {
410 mLastWallpaperX = target.mWallpaperX;
411 } else if (changingTarget.mWallpaperX >= 0) {
412 mLastWallpaperX = changingTarget.mWallpaperX;
413 }
414 if (target.mWallpaperY >= 0) {
415 mLastWallpaperY = target.mWallpaperY;
416 } else if (changingTarget.mWallpaperY >= 0) {
417 mLastWallpaperY = changingTarget.mWallpaperY;
418 }
419 if (target.mWallpaperDisplayOffsetX != Integer.MIN_VALUE) {
420 mLastWallpaperDisplayOffsetX = target.mWallpaperDisplayOffsetX;
421 } else if (changingTarget.mWallpaperDisplayOffsetX != Integer.MIN_VALUE) {
422 mLastWallpaperDisplayOffsetX = changingTarget.mWallpaperDisplayOffsetX;
423 }
424 if (target.mWallpaperDisplayOffsetY != Integer.MIN_VALUE) {
425 mLastWallpaperDisplayOffsetY = target.mWallpaperDisplayOffsetY;
426 } else if (changingTarget.mWallpaperDisplayOffsetY != Integer.MIN_VALUE) {
427 mLastWallpaperDisplayOffsetY = changingTarget.mWallpaperDisplayOffsetY;
428 }
429 if (target.mWallpaperXStep >= 0) {
430 mLastWallpaperXStep = target.mWallpaperXStep;
431 } else if (changingTarget.mWallpaperXStep >= 0) {
432 mLastWallpaperXStep = changingTarget.mWallpaperXStep;
433 }
434 if (target.mWallpaperYStep >= 0) {
435 mLastWallpaperYStep = target.mWallpaperYStep;
436 } else if (changingTarget.mWallpaperYStep >= 0) {
437 mLastWallpaperYStep = changingTarget.mWallpaperYStep;
438 }
439 }
440
441 for (int curTokenNdx = mWallpaperTokens.size() - 1; curTokenNdx >= 0; curTokenNdx--) {
Wale Ogunwalee4da0c12016-07-29 12:47:02 -0700442 mWallpaperTokens.get(curTokenNdx).updateWallpaperOffset(dw, dh, sync);
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700443 }
444 }
445
446 void clearLastWallpaperTimeoutTime() {
447 mLastWallpaperTimeoutTime = 0;
448 }
449
450 void wallpaperCommandComplete(IBinder window) {
451 if (mWaitingOnWallpaper != null &&
452 mWaitingOnWallpaper.mClient.asBinder() == window) {
453 mWaitingOnWallpaper = null;
Wale Ogunwaledb485de2018-10-29 09:47:07 -0700454 mService.mGlobalLock.notifyAll();
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700455 }
456 }
457
458 void wallpaperOffsetsComplete(IBinder window) {
459 if (mWaitingOnWallpaper != null &&
460 mWaitingOnWallpaper.mClient.asBinder() == window) {
461 mWaitingOnWallpaper = null;
Wale Ogunwaledb485de2018-10-29 09:47:07 -0700462 mService.mGlobalLock.notifyAll();
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700463 }
464 }
465
wilsonshihc32538e2018-11-07 17:27:34 +0800466 private void findWallpaperTarget() {
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800467 mFindResults.reset();
wilsonshihc32538e2018-11-07 17:27:34 +0800468 if (mDisplayContent.isStackVisible(WINDOWING_MODE_FREEFORM)) {
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -0800469 // In freeform mode we set the wallpaper as its own target, so we don't need an
470 // additional window to make it visible.
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800471 mFindResults.setUseTopWallpaperAsTarget(true);
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -0800472 }
Wale Ogunwale6cbba702016-06-28 16:27:31 -0700473
wilsonshihc32538e2018-11-07 17:27:34 +0800474 mDisplayContent.forAllWindows(mFindWallpaperTargetFunction, true /* traverseTopToBottom */);
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -0800475
Wale Ogunwale1e129a42016-11-21 13:03:47 -0800476 if (mFindResults.wallpaperTarget == null && mFindResults.useTopWallpaperAsTarget) {
477 mFindResults.setWallpaperTarget(mFindResults.topWallpaper);
Wale Ogunwale21fdd912015-08-20 12:34:57 -0700478 }
Wale Ogunwale5f61d042015-08-20 10:09:47 -0700479 }
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700480
Jorim Jaggife762342016-10-13 14:33:27 +0200481 private boolean isFullscreen(WindowManager.LayoutParams attrs) {
482 return attrs.x == 0 && attrs.y == 0
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -0800483 && attrs.width == MATCH_PARENT && attrs.height == MATCH_PARENT;
Jorim Jaggife762342016-10-13 14:33:27 +0200484 }
485
Wale Ogunwale0c4a40ef2016-10-07 07:06:40 -0700486 /** Updates the target wallpaper if needed and returns true if an update happened. */
wilsonshihc32538e2018-11-07 17:27:34 +0800487 private void updateWallpaperWindowsTarget(FindWallpaperTargetResult result) {
Wale Ogunwale5f61d042015-08-20 10:09:47 -0700488
Wale Ogunwale5f61d042015-08-20 10:09:47 -0700489 WindowState wallpaperTarget = result.wallpaperTarget;
Wale Ogunwale5f61d042015-08-20 10:09:47 -0700490
Wale Ogunwale0c4a40ef2016-10-07 07:06:40 -0700491 if (mWallpaperTarget == wallpaperTarget
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -0800492 || (mPrevWallpaperTarget != null && mPrevWallpaperTarget == wallpaperTarget)) {
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700493
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -0800494 if (mPrevWallpaperTarget == null) {
495 return;
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700496 }
497
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -0800498 // Is it time to stop animating?
499 if (!mPrevWallpaperTarget.isAnimatingLw()) {
500 if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG, "No longer animating wallpaper targets!");
501 mPrevWallpaperTarget = null;
502 mWallpaperTarget = wallpaperTarget;
503 }
504 return;
Wale Ogunwale0c4a40ef2016-10-07 07:06:40 -0700505 }
506
507 if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -0800508 "New wallpaper target: " + wallpaperTarget + " prevTarget: " + mWallpaperTarget);
Wale Ogunwale0c4a40ef2016-10-07 07:06:40 -0700509
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -0800510 mPrevWallpaperTarget = null;
Wale Ogunwale0c4a40ef2016-10-07 07:06:40 -0700511
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -0800512 final WindowState prevWallpaperTarget = mWallpaperTarget;
Wale Ogunwale0c4a40ef2016-10-07 07:06:40 -0700513 mWallpaperTarget = wallpaperTarget;
514
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -0800515 if (wallpaperTarget == null || prevWallpaperTarget == null) {
516 return;
Wale Ogunwale0c4a40ef2016-10-07 07:06:40 -0700517 }
518
519 // Now what is happening... if the current and new targets are animating,
520 // then we are in our super special mode!
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -0800521 boolean oldAnim = prevWallpaperTarget.isAnimatingLw();
Wale Ogunwale0c4a40ef2016-10-07 07:06:40 -0700522 boolean foundAnim = wallpaperTarget.isAnimatingLw();
523 if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
524 "New animation: " + foundAnim + " old animation: " + oldAnim);
525
526 if (!foundAnim || !oldAnim) {
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -0800527 return;
Wale Ogunwale0c4a40ef2016-10-07 07:06:40 -0700528 }
529
wilsonshihc32538e2018-11-07 17:27:34 +0800530 if (mDisplayContent.getWindow(w -> w == prevWallpaperTarget) == null) {
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -0800531 return;
Wale Ogunwale0c4a40ef2016-10-07 07:06:40 -0700532 }
533
Garfield Tane8d84ab2019-10-11 09:49:40 -0700534 final boolean newTargetHidden = wallpaperTarget.mActivityRecord != null
Issei Suzuki1669ea42019-11-06 14:20:59 +0100535 && !wallpaperTarget.mActivityRecord.mVisibleRequested;
Garfield Tane8d84ab2019-10-11 09:49:40 -0700536 final boolean oldTargetHidden = prevWallpaperTarget.mActivityRecord != null
Issei Suzuki1669ea42019-11-06 14:20:59 +0100537 && !prevWallpaperTarget.mActivityRecord.mVisibleRequested;
Wale Ogunwale0c4a40ef2016-10-07 07:06:40 -0700538
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -0800539 if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG, "Animating wallpapers:" + " old: "
540 + prevWallpaperTarget + " hidden=" + oldTargetHidden + " new: " + wallpaperTarget
541 + " hidden=" + newTargetHidden);
Wale Ogunwale0c4a40ef2016-10-07 07:06:40 -0700542
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -0800543 mPrevWallpaperTarget = prevWallpaperTarget;
Wale Ogunwale0c4a40ef2016-10-07 07:06:40 -0700544
545 if (newTargetHidden && !oldTargetHidden) {
546 if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG, "Old wallpaper still the target.");
547 // Use the old target if new target is hidden but old target
548 // is not. If they're both hidden, still use the new target.
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -0800549 mWallpaperTarget = prevWallpaperTarget;
Wale Ogunwale0c4a40ef2016-10-07 07:06:40 -0700550 } else if (newTargetHidden == oldTargetHidden
Garfield Tane8d84ab2019-10-11 09:49:40 -0700551 && !mDisplayContent.mOpeningApps.contains(wallpaperTarget.mActivityRecord)
552 && (mDisplayContent.mOpeningApps.contains(prevWallpaperTarget.mActivityRecord)
553 || mDisplayContent.mClosingApps.contains(prevWallpaperTarget.mActivityRecord))) {
Wale Ogunwale0c4a40ef2016-10-07 07:06:40 -0700554 // If they're both hidden (or both not hidden), prefer the one that's currently in
555 // opening or closing app list, this allows transition selection logic to better
556 // determine the wallpaper status of opening/closing apps.
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -0800557 mWallpaperTarget = prevWallpaperTarget;
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700558 }
559
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -0800560 result.setWallpaperTarget(wallpaperTarget);
Wale Ogunwale5f61d042015-08-20 10:09:47 -0700561 }
562
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -0800563 private void updateWallpaperTokens(boolean visible) {
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700564 for (int curTokenNdx = mWallpaperTokens.size() - 1; curTokenNdx >= 0; curTokenNdx--) {
Jorim Jaggi879ff722016-11-04 18:08:17 -0700565 final WallpaperWindowToken token = mWallpaperTokens.get(curTokenNdx);
Jorim Jaggib0fc8172017-11-23 17:04:08 +0000566 token.updateWallpaperWindows(visible);
Robert Carrdee1b3f2017-02-27 11:33:33 -0800567 token.getDisplayContent().assignWindowLayers(false);
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700568 }
Wale Ogunwale5f61d042015-08-20 10:09:47 -0700569 }
570
wilsonshihc32538e2018-11-07 17:27:34 +0800571 void adjustWallpaperWindows() {
572 mDisplayContent.mWallpaperMayChange = false;
Wale Ogunwale5f61d042015-08-20 10:09:47 -0700573
Wale Ogunwale5f61d042015-08-20 10:09:47 -0700574 // First find top-most window that has asked to be on top of the wallpaper;
575 // all wallpapers go behind it.
wilsonshihc32538e2018-11-07 17:27:34 +0800576 findWallpaperTarget();
577 updateWallpaperWindowsTarget(mFindResults);
Wale Ogunwale5f61d042015-08-20 10:09:47 -0700578
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -0800579 // The window is visible to the compositor...but is it visible to the user?
580 // That is what the wallpaper cares about.
581 final boolean visible = mWallpaperTarget != null && isWallpaperVisible(mWallpaperTarget);
wilsonshihc32538e2018-11-07 17:27:34 +0800582 if (DEBUG_WALLPAPER) {
583 Slog.v(TAG, "Wallpaper visibility: " + visible + " at display "
584 + mDisplayContent.getDisplayId());
585 }
Wale Ogunwale5f61d042015-08-20 10:09:47 -0700586
587 if (visible) {
588 if (mWallpaperTarget.mWallpaperX >= 0) {
589 mLastWallpaperX = mWallpaperTarget.mWallpaperX;
590 mLastWallpaperXStep = mWallpaperTarget.mWallpaperXStep;
591 }
592 if (mWallpaperTarget.mWallpaperY >= 0) {
593 mLastWallpaperY = mWallpaperTarget.mWallpaperY;
594 mLastWallpaperYStep = mWallpaperTarget.mWallpaperYStep;
595 }
596 if (mWallpaperTarget.mWallpaperDisplayOffsetX != Integer.MIN_VALUE) {
597 mLastWallpaperDisplayOffsetX = mWallpaperTarget.mWallpaperDisplayOffsetX;
598 }
599 if (mWallpaperTarget.mWallpaperDisplayOffsetY != Integer.MIN_VALUE) {
600 mLastWallpaperDisplayOffsetY = mWallpaperTarget.mWallpaperDisplayOffsetY;
601 }
602 }
603
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -0800604 updateWallpaperTokens(visible);
Wale Ogunwale5f61d042015-08-20 10:09:47 -0700605
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -0800606 if (DEBUG_WALLPAPER_LIGHT) Slog.d(TAG, "New wallpaper: target=" + mWallpaperTarget
607 + " prev=" + mPrevWallpaperTarget);
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700608 }
609
610 boolean processWallpaperDrawPendingTimeout() {
611 if (mWallpaperDrawState == WALLPAPER_DRAW_PENDING) {
612 mWallpaperDrawState = WALLPAPER_DRAW_TIMEOUT;
Adrian Roosb125e0b2019-10-02 14:55:14 +0200613 if (DEBUG_WALLPAPER) {
614 Slog.v(TAG, "*** WALLPAPER DRAW TIMEOUT");
615 }
Winson Chunge2d72172018-01-25 17:46:20 +0000616
Winson Chungfe571032019-06-18 11:22:53 -0700617 // If there was a pending recents animation, start the animation anyways (it's better
618 // to not see the wallpaper than for the animation to not start)
Winson Chunge2d72172018-01-25 17:46:20 +0000619 if (mService.getRecentsAnimationController() != null) {
Winson Chungfe571032019-06-18 11:22:53 -0700620 mService.getRecentsAnimationController().startAnimation();
Winson Chunge2d72172018-01-25 17:46:20 +0000621 }
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700622 return true;
623 }
624 return false;
625 }
626
627 boolean wallpaperTransitionReady() {
628 boolean transitionReady = true;
629 boolean wallpaperReady = true;
630 for (int curTokenIndex = mWallpaperTokens.size() - 1;
631 curTokenIndex >= 0 && wallpaperReady; curTokenIndex--) {
Jorim Jaggi879ff722016-11-04 18:08:17 -0700632 final WallpaperWindowToken token = mWallpaperTokens.get(curTokenIndex);
Wale Ogunwalee4da0c12016-07-29 12:47:02 -0700633 if (token.hasVisibleNotDrawnWallpaper()) {
634 // We've told this wallpaper to be visible, but it is not drawn yet
635 wallpaperReady = false;
636 if (mWallpaperDrawState != WALLPAPER_DRAW_TIMEOUT) {
637 // wait for this wallpaper until it is drawn or timeout
638 transitionReady = false;
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700639 }
Wale Ogunwalee4da0c12016-07-29 12:47:02 -0700640 if (mWallpaperDrawState == WALLPAPER_DRAW_NORMAL) {
641 mWallpaperDrawState = WALLPAPER_DRAW_PENDING;
wilsonshihc32538e2018-11-07 17:27:34 +0800642 mService.mH.removeMessages(WALLPAPER_DRAW_PENDING_TIMEOUT, this);
643 mService.mH.sendMessageDelayed(
644 mService.mH.obtainMessage(WALLPAPER_DRAW_PENDING_TIMEOUT, this),
645 WALLPAPER_DRAW_PENDING_TIMEOUT_DURATION);
646
Wale Ogunwalee4da0c12016-07-29 12:47:02 -0700647 }
Adrian Roosb125e0b2019-10-02 14:55:14 +0200648 if (DEBUG_WALLPAPER) {
649 Slog.v(TAG,
650 "Wallpaper should be visible but has not been drawn yet. "
651 + "mWallpaperDrawState=" + mWallpaperDrawState);
652 }
Wale Ogunwalee4da0c12016-07-29 12:47:02 -0700653 break;
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700654 }
655 }
656 if (wallpaperReady) {
657 mWallpaperDrawState = WALLPAPER_DRAW_NORMAL;
wilsonshihc32538e2018-11-07 17:27:34 +0800658 mService.mH.removeMessages(WALLPAPER_DRAW_PENDING_TIMEOUT, this);
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700659 }
660
661 return transitionReady;
662 }
663
Wale Ogunwale0c4a40ef2016-10-07 07:06:40 -0700664 /**
665 * Adjusts the wallpaper windows if the input display has a pending wallpaper layout or one of
666 * the opening apps should be a wallpaper target.
667 */
Garfield Tane8d84ab2019-10-11 09:49:40 -0700668 void adjustWallpaperWindowsForAppTransitionIfNeeded(ArraySet<ActivityRecord> openingApps,
669 ArraySet<ActivityRecord> changingApps) {
Wale Ogunwale0c4a40ef2016-10-07 07:06:40 -0700670 boolean adjust = false;
wilsonshihc32538e2018-11-07 17:27:34 +0800671 if ((mDisplayContent.pendingLayoutChanges & FINISH_LAYOUT_REDO_WALLPAPER) != 0) {
Wale Ogunwale0c4a40ef2016-10-07 07:06:40 -0700672 adjust = true;
673 } else {
674 for (int i = openingApps.size() - 1; i >= 0; --i) {
Garfield Tane8d84ab2019-10-11 09:49:40 -0700675 final ActivityRecord activity = openingApps.valueAt(i);
676 if (activity.windowsCanBeWallpaperTarget()) {
Wale Ogunwale0c4a40ef2016-10-07 07:06:40 -0700677 adjust = true;
678 break;
679 }
680 }
Evan Rosky2289ba12018-11-19 18:28:18 -0800681 if (!adjust) {
682 for (int i = changingApps.size() - 1; i >= 0; --i) {
Garfield Tane8d84ab2019-10-11 09:49:40 -0700683 final ActivityRecord activity = changingApps.valueAt(i);
684 if (activity.windowsCanBeWallpaperTarget()) {
Evan Rosky2289ba12018-11-19 18:28:18 -0800685 adjust = true;
686 break;
687 }
688 }
689 }
Wale Ogunwale0c4a40ef2016-10-07 07:06:40 -0700690 }
691
Wale Ogunwale0303c572016-10-20 10:16:29 -0700692 if (adjust) {
wilsonshihc32538e2018-11-07 17:27:34 +0800693 adjustWallpaperWindows();
Wale Ogunwale0c4a40ef2016-10-07 07:06:40 -0700694 }
695 }
696
Jorim Jaggi879ff722016-11-04 18:08:17 -0700697 void addWallpaperToken(WallpaperWindowToken token) {
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700698 mWallpaperTokens.add(token);
699 }
700
Jorim Jaggi879ff722016-11-04 18:08:17 -0700701 void removeWallpaperToken(WallpaperWindowToken token) {
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700702 mWallpaperTokens.remove(token);
703 }
704
Vishnu Naire6e2b0f2019-02-21 10:41:00 -0800705
706 @VisibleForTesting
707 boolean canScreenshotWallpaper() {
708 return canScreenshotWallpaper(getTopVisibleWallpaper());
709 }
710
711 private boolean canScreenshotWallpaper(WindowState wallpaperWindowState) {
712 if (!mService.mPolicy.isScreenOn()) {
713 if (DEBUG_SCREENSHOT) {
714 Slog.i(TAG_WM, "Attempted to take screenshot while display was off.");
715 }
716 return false;
717 }
718
719 if (wallpaperWindowState == null) {
720 if (DEBUG_SCREENSHOT) {
721 Slog.i(TAG_WM, "No visible wallpaper to screenshot");
722 }
723 return false;
724 }
725 return true;
726 }
727
chaviw0315a1a2018-03-05 15:28:35 -0800728 /**
729 * Take a screenshot of the wallpaper if it's visible.
730 *
731 * @return Bitmap of the wallpaper
732 */
733 Bitmap screenshotWallpaperLocked() {
chaviw0315a1a2018-03-05 15:28:35 -0800734 final WindowState wallpaperWindowState = getTopVisibleWallpaper();
Vishnu Naire6e2b0f2019-02-21 10:41:00 -0800735 if (!canScreenshotWallpaper(wallpaperWindowState)) {
chaviw0315a1a2018-03-05 15:28:35 -0800736 return null;
737 }
738
739 final Rect bounds = wallpaperWindowState.getBounds();
740 bounds.offsetTo(0, 0);
741
Peiyong Line3e5efd2019-03-21 20:59:47 +0000742 SurfaceControl.ScreenshotGraphicBuffer wallpaperBuffer = SurfaceControl.captureLayers(
Vishnu Nairbc9beab2019-06-25 17:28:58 -0700743 wallpaperWindowState.getSurfaceControl(), bounds, 1 /* frameScale */);
chaviw0315a1a2018-03-05 15:28:35 -0800744
745 if (wallpaperBuffer == null) {
746 Slog.w(TAG_WM, "Failed to screenshot wallpaper");
747 return null;
748 }
Peiyong Line3e5efd2019-03-21 20:59:47 +0000749 return Bitmap.wrapHardwareBuffer(
Sunny Goyal62915b22019-04-10 12:28:47 -0700750 wallpaperBuffer.getGraphicBuffer(), wallpaperBuffer.getColorSpace());
chaviw0315a1a2018-03-05 15:28:35 -0800751 }
752
753 private WindowState getTopVisibleWallpaper() {
754 mTmpTopWallpaper = null;
755
756 for (int curTokenNdx = mWallpaperTokens.size() - 1; curTokenNdx >= 0; curTokenNdx--) {
757 final WallpaperWindowToken token = mWallpaperTokens.get(curTokenNdx);
758 token.forAllWindows(w -> {
759 final WindowStateAnimator winAnim = w.mWinAnimator;
760 if (winAnim != null && winAnim.getShown() && winAnim.mLastAlpha > 0f) {
761 mTmpTopWallpaper = w;
762 return true;
763 }
764 return false;
765 }, true /* traverseTopToBottom */);
766 }
767
768 return mTmpTopWallpaper;
769 }
770
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700771 void dump(PrintWriter pw, String prefix) {
wilsonshihc32538e2018-11-07 17:27:34 +0800772 pw.print(prefix); pw.print("displayId="); pw.println(mDisplayContent.getDisplayId());
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700773 pw.print(prefix); pw.print("mWallpaperTarget="); pw.println(mWallpaperTarget);
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -0800774 if (mPrevWallpaperTarget != null) {
775 pw.print(prefix); pw.print("mPrevWallpaperTarget="); pw.println(mPrevWallpaperTarget);
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700776 }
777 pw.print(prefix); pw.print("mLastWallpaperX="); pw.print(mLastWallpaperX);
778 pw.print(" mLastWallpaperY="); pw.println(mLastWallpaperY);
779 if (mLastWallpaperDisplayOffsetX != Integer.MIN_VALUE
780 || mLastWallpaperDisplayOffsetY != Integer.MIN_VALUE) {
781 pw.print(prefix);
782 pw.print("mLastWallpaperDisplayOffsetX="); pw.print(mLastWallpaperDisplayOffsetX);
783 pw.print(" mLastWallpaperDisplayOffsetY="); pw.println(mLastWallpaperDisplayOffsetY);
784 }
785 }
786
Wale Ogunwale5f61d042015-08-20 10:09:47 -0700787 /** Helper class for storing the results of a wallpaper target find operation. */
788 final private static class FindWallpaperTargetResult {
Wale Ogunwale5f61d042015-08-20 10:09:47 -0700789 WindowState topWallpaper = null;
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -0800790 boolean useTopWallpaperAsTarget = false;
Wale Ogunwale5f61d042015-08-20 10:09:47 -0700791 WindowState wallpaperTarget = null;
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -0800792 boolean resetTopWallpaper = false;
Wale Ogunwale5f61d042015-08-20 10:09:47 -0700793
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -0800794 void setTopWallpaper(WindowState win) {
Wale Ogunwale5f61d042015-08-20 10:09:47 -0700795 topWallpaper = win;
Wale Ogunwale5f61d042015-08-20 10:09:47 -0700796 }
797
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -0800798 void setWallpaperTarget(WindowState win) {
Wale Ogunwale5f61d042015-08-20 10:09:47 -0700799 wallpaperTarget = win;
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -0800800 }
801
802 void setUseTopWallpaperAsTarget(boolean topWallpaperAsTarget) {
803 useTopWallpaperAsTarget = topWallpaperAsTarget;
Wale Ogunwale5f61d042015-08-20 10:09:47 -0700804 }
805
806 void reset() {
Wale Ogunwale5f61d042015-08-20 10:09:47 -0700807 topWallpaper = null;
Wale Ogunwale5f61d042015-08-20 10:09:47 -0700808 wallpaperTarget = null;
Wale Ogunwalef4ebe2e2016-11-09 13:24:43 -0800809 useTopWallpaperAsTarget = false;
810 resetTopWallpaper = false;
Wale Ogunwale5f61d042015-08-20 10:09:47 -0700811 }
812 }
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700813}