blob: 250d381e614b8e42514251322627365b537c5eb2 [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 Ogunwale3797c222015-10-27 14:21:58 -070019import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
Wale Ogunwalee8069dc2015-08-18 09:52:01 -070020import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
Jorim Jaggife762342016-10-13 14:33:27 +020021import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;
Wale Ogunwalee8069dc2015-08-18 09:52:01 -070022import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
Wale Ogunwalee8069dc2015-08-18 09:52:01 -070023import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
Wale Ogunwale0c4a40ef2016-10-07 07:06:40 -070024import static android.view.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
Jorim Jaggife762342016-10-13 14:33:27 +020025
26import static com.android.server.wm.AppTransition.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_WITH_WALLPAPER;
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -080027import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_APP_TRANSITIONS;
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -080028import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER;
29import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_WALLPAPER_LIGHT;
30import static com.android.server.wm.WindowManagerDebugConfig.TAG_WITH_CLASS_NAME;
31import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
Wale Ogunwalee8069dc2015-08-18 09:52:01 -070032import static com.android.server.wm.WindowManagerService.H.WALLPAPER_DRAW_PENDING_TIMEOUT;
33import static com.android.server.wm.WindowManagerService.TYPE_LAYER_MULTIPLIER;
34import static com.android.server.wm.WindowManagerService.TYPE_LAYER_OFFSET;
35
36import android.os.Bundle;
37import android.os.Debug;
38import android.os.IBinder;
39import android.os.RemoteException;
40import android.os.SystemClock;
Wale Ogunwale0c4a40ef2016-10-07 07:06:40 -070041import android.util.ArraySet;
Wale Ogunwalee8069dc2015-08-18 09:52:01 -070042import android.util.Slog;
43import android.view.DisplayInfo;
44import android.view.WindowManager;
Jorim Jaggife762342016-10-13 14:33:27 +020045import android.view.animation.Animation;
Wale Ogunwalee8069dc2015-08-18 09:52:01 -070046
47import java.io.PrintWriter;
48import java.util.ArrayList;
49
50/**
51 * Controls wallpaper windows visibility, ordering, and so on.
52 * NOTE: All methods in this class must be called with the window manager service lock held.
53 */
54class WallpaperController {
Filip Gruszczynski0bd180d2015-12-07 15:43:52 -080055 private static final String TAG = TAG_WITH_CLASS_NAME ? "WallpaperController" : TAG_WM;
Wale Ogunwalee8069dc2015-08-18 09:52:01 -070056 final private WindowManagerService mService;
57
58 private final ArrayList<WindowToken> mWallpaperTokens = new ArrayList<>();
59
60 // If non-null, this is the currently visible window that is associated
61 // with the wallpaper.
62 private WindowState mWallpaperTarget = null;
63 // If non-null, we are in the middle of animating from one wallpaper target
64 // to another, and this is the lower one in Z-order.
65 private WindowState mLowerWallpaperTarget = null;
66 // If non-null, we are in the middle of animating from one wallpaper target
67 // to another, and this is the higher one in Z-order.
68 private WindowState mUpperWallpaperTarget = null;
69
70 private int mWallpaperAnimLayerAdjustment;
71
72 private float mLastWallpaperX = -1;
73 private float mLastWallpaperY = -1;
74 private float mLastWallpaperXStep = -1;
75 private float mLastWallpaperYStep = -1;
76 private int mLastWallpaperDisplayOffsetX = Integer.MIN_VALUE;
77 private int mLastWallpaperDisplayOffsetY = Integer.MIN_VALUE;
78
79 // This is set when we are waiting for a wallpaper to tell us it is done
80 // changing its scroll position.
81 WindowState mWaitingOnWallpaper;
82
83 // The last time we had a timeout when waiting for a wallpaper.
84 private long mLastWallpaperTimeoutTime;
85 // We give a wallpaper up to 150ms to finish scrolling.
86 private static final long WALLPAPER_TIMEOUT = 150;
87 // Time we wait after a timeout before trying to wait again.
88 private static final long WALLPAPER_TIMEOUT_RECOVERY = 10000;
89
90 // Set to the wallpaper window we would like to hide once the transition animations are done.
91 // This is useful in cases where we don't want the wallpaper to be hidden when the close app
92 // is a wallpaper target and is done animating out, but the opening app isn't a wallpaper
93 // target and isn't done animating in.
Wale Ogunwalee4da0c12016-07-29 12:47:02 -070094 WindowState mDeferredHideWallpaper = null;
Wale Ogunwalee8069dc2015-08-18 09:52:01 -070095
96 // We give a wallpaper up to 500ms to finish drawing before playing app transitions.
97 private static final long WALLPAPER_DRAW_PENDING_TIMEOUT_DURATION = 500;
98 private static final int WALLPAPER_DRAW_NORMAL = 0;
99 private static final int WALLPAPER_DRAW_PENDING = 1;
100 private static final int WALLPAPER_DRAW_TIMEOUT = 2;
101 private int mWallpaperDrawState = WALLPAPER_DRAW_NORMAL;
102
Wale Ogunwale5f61d042015-08-20 10:09:47 -0700103 private final FindWallpaperTargetResult mFindResults = new FindWallpaperTargetResult();
104
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700105 public WallpaperController(WindowManagerService service) {
106 mService = service;
107 }
108
109 WindowState getWallpaperTarget() {
110 return mWallpaperTarget;
111 }
112
113 WindowState getLowerWallpaperTarget() {
114 return mLowerWallpaperTarget;
115 }
116
117 WindowState getUpperWallpaperTarget() {
118 return mUpperWallpaperTarget;
119 }
120
121 boolean isWallpaperTarget(WindowState win) {
122 return win == mWallpaperTarget;
123 }
124
125 boolean isBelowWallpaperTarget(WindowState win) {
126 return mWallpaperTarget != null && mWallpaperTarget.mLayer >= win.mBaseLayer;
127 }
128
129 boolean isWallpaperVisible() {
130 return isWallpaperVisible(mWallpaperTarget);
131 }
132
Jorim Jaggife762342016-10-13 14:33:27 +0200133 /**
134 * Starts {@param a} on all wallpaper windows.
135 */
136 void startWallpaperAnimation(Animation a) {
137 for (int curTokenNdx = mWallpaperTokens.size() - 1; curTokenNdx >= 0; curTokenNdx--) {
138 final WindowToken token = mWallpaperTokens.get(curTokenNdx);
139 token.startAnimation(a);
140 }
141 }
142
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700143 private boolean isWallpaperVisible(WindowState wallpaperTarget) {
144 if (DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper vis: target " + wallpaperTarget + ", obscured="
145 + (wallpaperTarget != null ? Boolean.toString(wallpaperTarget.mObscured) : "??")
146 + " anim=" + ((wallpaperTarget != null && wallpaperTarget.mAppToken != null)
147 ? wallpaperTarget.mAppToken.mAppAnimator.animation : null)
148 + " upper=" + mUpperWallpaperTarget
149 + " lower=" + mLowerWallpaperTarget);
150 return (wallpaperTarget != null
151 && (!wallpaperTarget.mObscured || (wallpaperTarget.mAppToken != null
152 && wallpaperTarget.mAppToken.mAppAnimator.animation != null)))
153 || mUpperWallpaperTarget != null
154 || mLowerWallpaperTarget != null;
155 }
156
157 boolean isWallpaperTargetAnimating() {
Jorim Jaggi5c80c412016-04-19 20:03:47 -0700158 return mWallpaperTarget != null && mWallpaperTarget.mWinAnimator.isAnimationSet()
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700159 && !mWallpaperTarget.mWinAnimator.isDummyAnimation();
160 }
161
162 void updateWallpaperVisibility() {
Filip Gruszczynski63a35e22015-11-05 15:38:59 -0800163 final boolean visible = isWallpaperVisible(mWallpaperTarget);
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700164
165 for (int curTokenNdx = mWallpaperTokens.size() - 1; curTokenNdx >= 0; curTokenNdx--) {
Wale Ogunwalee4da0c12016-07-29 12:47:02 -0700166 final WindowToken token = mWallpaperTokens.get(curTokenNdx);
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -0700167 token.updateWallpaperVisibility(visible);
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700168 }
169 }
170
171 void hideDeferredWallpapersIfNeeded() {
172 if (mDeferredHideWallpaper != null) {
173 hideWallpapers(mDeferredHideWallpaper);
174 mDeferredHideWallpaper = null;
175 }
176 }
177
178 void hideWallpapers(final WindowState winGoingAway) {
179 if (mWallpaperTarget != null
180 && (mWallpaperTarget != winGoingAway || mLowerWallpaperTarget != null)) {
181 return;
182 }
183 if (mService.mAppTransition.isRunning()) {
184 // Defer hiding the wallpaper when app transition is running until the animations
185 // are done.
186 mDeferredHideWallpaper = winGoingAway;
187 return;
188 }
189
190 final boolean wasDeferred = (mDeferredHideWallpaper == winGoingAway);
191 for (int i = mWallpaperTokens.size() - 1; i >= 0; i--) {
192 final WindowToken token = mWallpaperTokens.get(i);
Wale Ogunwalee4da0c12016-07-29 12:47:02 -0700193 token.hideWallpaperToken(wasDeferred, "hideWallpapers");
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700194 if (DEBUG_WALLPAPER_LIGHT && !token.hidden) Slog.d(TAG, "Hiding wallpaper " + token
195 + " from " + winGoingAway + " target=" + mWallpaperTarget + " lower="
196 + mLowerWallpaperTarget + "\n" + Debug.getCallers(5, " "));
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700197 }
198 }
199
200 boolean updateWallpaperOffset(WindowState wallpaperWin, int dw, int dh, boolean sync) {
201 boolean rawChanged = false;
Winson4b4ba902016-07-27 19:45:52 -0700202 // Set the default wallpaper x-offset to either edge of the screen (depending on RTL), to
203 // match the behavior of most Launchers
204 float defaultWallpaperX = wallpaperWin.isRtl() ? 1f : 0f;
205 float wpx = mLastWallpaperX >= 0 ? mLastWallpaperX : defaultWallpaperX;
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700206 float wpxs = mLastWallpaperXStep >= 0 ? mLastWallpaperXStep : -1.0f;
207 int availw = wallpaperWin.mFrame.right - wallpaperWin.mFrame.left - dw;
208 int offset = availw > 0 ? -(int)(availw * wpx + .5f) : 0;
209 if (mLastWallpaperDisplayOffsetX != Integer.MIN_VALUE) {
210 offset += mLastWallpaperDisplayOffsetX;
211 }
212 boolean changed = wallpaperWin.mXOffset != offset;
213 if (changed) {
214 if (DEBUG_WALLPAPER) Slog.v(TAG, "Update wallpaper " + wallpaperWin + " x: " + offset);
215 wallpaperWin.mXOffset = offset;
216 }
217 if (wallpaperWin.mWallpaperX != wpx || wallpaperWin.mWallpaperXStep != wpxs) {
218 wallpaperWin.mWallpaperX = wpx;
219 wallpaperWin.mWallpaperXStep = wpxs;
220 rawChanged = true;
221 }
222
223 float wpy = mLastWallpaperY >= 0 ? mLastWallpaperY : 0.5f;
224 float wpys = mLastWallpaperYStep >= 0 ? mLastWallpaperYStep : -1.0f;
225 int availh = wallpaperWin.mFrame.bottom - wallpaperWin.mFrame.top - dh;
226 offset = availh > 0 ? -(int)(availh * wpy + .5f) : 0;
227 if (mLastWallpaperDisplayOffsetY != Integer.MIN_VALUE) {
228 offset += mLastWallpaperDisplayOffsetY;
229 }
230 if (wallpaperWin.mYOffset != offset) {
231 if (DEBUG_WALLPAPER) Slog.v(TAG, "Update wallpaper " + wallpaperWin + " y: " + offset);
232 changed = true;
233 wallpaperWin.mYOffset = offset;
234 }
235 if (wallpaperWin.mWallpaperY != wpy || wallpaperWin.mWallpaperYStep != wpys) {
236 wallpaperWin.mWallpaperY = wpy;
237 wallpaperWin.mWallpaperYStep = wpys;
238 rawChanged = true;
239 }
240
241 if (rawChanged && (wallpaperWin.mAttrs.privateFlags &
242 WindowManager.LayoutParams.PRIVATE_FLAG_WANTS_OFFSET_NOTIFICATIONS) != 0) {
243 try {
244 if (DEBUG_WALLPAPER) Slog.v(TAG, "Report new wp offset "
245 + wallpaperWin + " x=" + wallpaperWin.mWallpaperX
246 + " y=" + wallpaperWin.mWallpaperY);
247 if (sync) {
248 mWaitingOnWallpaper = wallpaperWin;
249 }
250 wallpaperWin.mClient.dispatchWallpaperOffsets(
251 wallpaperWin.mWallpaperX, wallpaperWin.mWallpaperY,
252 wallpaperWin.mWallpaperXStep, wallpaperWin.mWallpaperYStep, sync);
253 if (sync) {
254 if (mWaitingOnWallpaper != null) {
255 long start = SystemClock.uptimeMillis();
256 if ((mLastWallpaperTimeoutTime + WALLPAPER_TIMEOUT_RECOVERY)
257 < start) {
258 try {
259 if (DEBUG_WALLPAPER) Slog.v(TAG,
260 "Waiting for offset complete...");
261 mService.mWindowMap.wait(WALLPAPER_TIMEOUT);
262 } catch (InterruptedException e) {
263 }
264 if (DEBUG_WALLPAPER) Slog.v(TAG, "Offset complete!");
265 if ((start + WALLPAPER_TIMEOUT) < SystemClock.uptimeMillis()) {
266 Slog.i(TAG, "Timeout waiting for wallpaper to offset: "
267 + wallpaperWin);
268 mLastWallpaperTimeoutTime = start;
269 }
270 }
271 mWaitingOnWallpaper = null;
272 }
273 }
274 } catch (RemoteException e) {
275 }
276 }
277
278 return changed;
279 }
280
281 void setWindowWallpaperPosition(
282 WindowState window, float x, float y, float xStep, float yStep) {
283 if (window.mWallpaperX != x || window.mWallpaperY != y) {
284 window.mWallpaperX = x;
285 window.mWallpaperY = y;
286 window.mWallpaperXStep = xStep;
287 window.mWallpaperYStep = yStep;
288 updateWallpaperOffsetLocked(window, true);
289 }
290 }
291
292 void setWindowWallpaperDisplayOffset(WindowState window, int x, int y) {
293 if (window.mWallpaperDisplayOffsetX != x || window.mWallpaperDisplayOffsetY != y) {
294 window.mWallpaperDisplayOffsetX = x;
295 window.mWallpaperDisplayOffsetY = y;
296 updateWallpaperOffsetLocked(window, true);
297 }
298 }
299
300 Bundle sendWindowWallpaperCommand(
301 WindowState window, String action, int x, int y, int z, Bundle extras, boolean sync) {
302 if (window == mWallpaperTarget
303 || window == mLowerWallpaperTarget
304 || window == mUpperWallpaperTarget) {
305 boolean doWait = sync;
306 for (int curTokenNdx = mWallpaperTokens.size() - 1; curTokenNdx >= 0; curTokenNdx--) {
Wale Ogunwalee4da0c12016-07-29 12:47:02 -0700307 final WindowToken token = mWallpaperTokens.get(curTokenNdx);
308 token.sendWindowWallpaperCommand(action, x, y, z, extras, sync);
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700309 }
310
311 if (doWait) {
312 // TODO: Need to wait for result.
313 }
314 }
315
316 return null;
317 }
318
Wale Ogunwaleb0f3b832016-10-17 10:13:07 -0700319 private void updateWallpaperOffsetLocked(WindowState changingTarget, boolean sync) {
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700320 final DisplayContent displayContent = changingTarget.getDisplayContent();
321 if (displayContent == null) {
322 return;
323 }
324 final DisplayInfo displayInfo = displayContent.getDisplayInfo();
325 final int dw = displayInfo.logicalWidth;
326 final int dh = displayInfo.logicalHeight;
327
328 WindowState target = mWallpaperTarget;
329 if (target != null) {
330 if (target.mWallpaperX >= 0) {
331 mLastWallpaperX = target.mWallpaperX;
332 } else if (changingTarget.mWallpaperX >= 0) {
333 mLastWallpaperX = changingTarget.mWallpaperX;
334 }
335 if (target.mWallpaperY >= 0) {
336 mLastWallpaperY = target.mWallpaperY;
337 } else if (changingTarget.mWallpaperY >= 0) {
338 mLastWallpaperY = changingTarget.mWallpaperY;
339 }
340 if (target.mWallpaperDisplayOffsetX != Integer.MIN_VALUE) {
341 mLastWallpaperDisplayOffsetX = target.mWallpaperDisplayOffsetX;
342 } else if (changingTarget.mWallpaperDisplayOffsetX != Integer.MIN_VALUE) {
343 mLastWallpaperDisplayOffsetX = changingTarget.mWallpaperDisplayOffsetX;
344 }
345 if (target.mWallpaperDisplayOffsetY != Integer.MIN_VALUE) {
346 mLastWallpaperDisplayOffsetY = target.mWallpaperDisplayOffsetY;
347 } else if (changingTarget.mWallpaperDisplayOffsetY != Integer.MIN_VALUE) {
348 mLastWallpaperDisplayOffsetY = changingTarget.mWallpaperDisplayOffsetY;
349 }
350 if (target.mWallpaperXStep >= 0) {
351 mLastWallpaperXStep = target.mWallpaperXStep;
352 } else if (changingTarget.mWallpaperXStep >= 0) {
353 mLastWallpaperXStep = changingTarget.mWallpaperXStep;
354 }
355 if (target.mWallpaperYStep >= 0) {
356 mLastWallpaperYStep = target.mWallpaperYStep;
357 } else if (changingTarget.mWallpaperYStep >= 0) {
358 mLastWallpaperYStep = changingTarget.mWallpaperYStep;
359 }
360 }
361
362 for (int curTokenNdx = mWallpaperTokens.size() - 1; curTokenNdx >= 0; curTokenNdx--) {
Wale Ogunwalee4da0c12016-07-29 12:47:02 -0700363 mWallpaperTokens.get(curTokenNdx).updateWallpaperOffset(dw, dh, sync);
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700364 }
365 }
366
367 void clearLastWallpaperTimeoutTime() {
368 mLastWallpaperTimeoutTime = 0;
369 }
370
371 void wallpaperCommandComplete(IBinder window) {
372 if (mWaitingOnWallpaper != null &&
373 mWaitingOnWallpaper.mClient.asBinder() == window) {
374 mWaitingOnWallpaper = null;
375 mService.mWindowMap.notifyAll();
376 }
377 }
378
379 void wallpaperOffsetsComplete(IBinder window) {
380 if (mWaitingOnWallpaper != null &&
381 mWaitingOnWallpaper.mClient.asBinder() == window) {
382 mWaitingOnWallpaper = null;
383 mService.mWindowMap.notifyAll();
384 }
385 }
386
387 int getAnimLayerAdjustment() {
388 return mWallpaperAnimLayerAdjustment;
389 }
390
Wale Ogunwalef7cab102016-10-25 15:25:14 -0700391 private void findWallpaperTarget(ReadOnlyWindowList windows, FindWallpaperTargetResult result) {
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700392 final WindowAnimator winAnimator = mService.mAnimator;
Wale Ogunwale5f61d042015-08-20 10:09:47 -0700393 result.reset();
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700394 WindowState w = null;
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700395 int windowDetachedI = -1;
Wale Ogunwale21fdd912015-08-20 12:34:57 -0700396 boolean resetTopWallpaper = false;
397 boolean inFreeformSpace = false;
Filip Gruszczynski51cb83e2015-11-05 09:32:19 -0800398 boolean replacing = false;
Wale Ogunwale6cbba702016-06-28 16:27:31 -0700399 boolean keyguardGoingAwayWithWallpaper = false;
Jorim Jaggife762342016-10-13 14:33:27 +0200400 boolean needsShowWhenLockedWallpaper = false;
Wale Ogunwale6cbba702016-06-28 16:27:31 -0700401
Wale Ogunwale5f61d042015-08-20 10:09:47 -0700402 for (int i = windows.size() - 1; i >= 0; i--) {
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700403 w = windows.get(i);
404 if ((w.mAttrs.type == TYPE_WALLPAPER)) {
Wale Ogunwale21fdd912015-08-20 12:34:57 -0700405 if (result.topWallpaper == null || resetTopWallpaper) {
Wale Ogunwale5f61d042015-08-20 10:09:47 -0700406 result.setTopWallpaper(w, i);
Wale Ogunwale21fdd912015-08-20 12:34:57 -0700407 resetTopWallpaper = false;
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700408 }
409 continue;
410 }
Wale Ogunwale21fdd912015-08-20 12:34:57 -0700411 resetTopWallpaper = true;
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700412 if (w != winAnimator.mWindowDetachedWallpaper && w.mAppToken != null) {
413 // If this window's app token is hidden and not animating,
414 // it is of no interest to us.
415 if (w.mAppToken.hidden && w.mAppToken.mAppAnimator.animation == null) {
416 if (DEBUG_WALLPAPER) Slog.v(TAG,
417 "Skipping hidden and not animating token: " + w);
418 continue;
419 }
420 }
421 if (DEBUG_WALLPAPER) Slog.v(TAG, "Win #" + i + " " + w + ": isOnScreen="
422 + w.isOnScreen() + " mDrawState=" + w.mWinAnimator.mDrawState);
423
Wale Ogunwale21fdd912015-08-20 12:34:57 -0700424 if (!inFreeformSpace) {
425 TaskStack stack = w.getStack();
426 inFreeformSpace = stack != null && stack.mStackId == FREEFORM_WORKSPACE_STACK_ID;
427 }
428
Wale Ogunwale6cbba702016-06-28 16:27:31 -0700429 replacing |= w.mWillReplaceWindow;
430 keyguardGoingAwayWithWallpaper |= (w.mAppToken != null
Jorim Jaggife762342016-10-13 14:33:27 +0200431 && AppTransition.isKeyguardGoingAwayTransit(
432 w.mAppToken.mAppAnimator.getTransit())
433 && (w.mAppToken.mAppAnimator.getTransitFlags()
434 & TRANSIT_FLAG_KEYGUARD_GOING_AWAY_WITH_WALLPAPER) != 0);
435
436 if ((w.mAttrs.flags & FLAG_SHOW_WHEN_LOCKED) != 0
437 && mService.mPolicy.isKeyguardLocked()
438 && mService.mPolicy.isKeyguardOccluded()) {
439 // The lowest show when locked window decides whether we need to put the wallpaper
440 // behind.
441 needsShowWhenLockedWallpaper = !isFullscreen(w.mAttrs)
442 || (w.mAppToken != null && !w.mAppToken.fillsParent());
443 }
Filip Gruszczynski51cb83e2015-11-05 09:32:19 -0800444
Wale Ogunwale6cbba702016-06-28 16:27:31 -0700445 final boolean hasWallpaper = (w.mAttrs.flags & FLAG_SHOW_WALLPAPER) != 0;
Filip Gruszczynski51cb83e2015-11-05 09:32:19 -0800446 if (hasWallpaper && w.isOnScreen() && (mWallpaperTarget == w || w.isDrawFinishedLw())) {
Wale Ogunwale5f61d042015-08-20 10:09:47 -0700447 if (DEBUG_WALLPAPER) Slog.v(TAG, "Found wallpaper target: #" + i + "=" + w);
448 result.setWallpaperTarget(w, i);
Jorim Jaggi5c80c412016-04-19 20:03:47 -0700449 if (w == mWallpaperTarget && w.mWinAnimator.isAnimationSet()) {
Wale Ogunwale5f61d042015-08-20 10:09:47 -0700450 // The current wallpaper target is animating, so we'll look behind it for
451 // another possible target and figure out what is going on later.
452 if (DEBUG_WALLPAPER) Slog.v(TAG,
453 "Win " + w + ": token animating, looking behind.");
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700454 continue;
455 }
456 break;
457 } else if (w == winAnimator.mWindowDetachedWallpaper) {
458 windowDetachedI = i;
459 }
460 }
461
Wale Ogunwale6cbba702016-06-28 16:27:31 -0700462 if (result.wallpaperTarget != null) {
463 return;
464 }
465
466 if (windowDetachedI >= 0) {
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700467 if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
Wale Ogunwale5f61d042015-08-20 10:09:47 -0700468 "Found animating detached wallpaper activity: #" + windowDetachedI + "=" + w);
469 result.setWallpaperTarget(w, windowDetachedI);
Wale Ogunwale6cbba702016-06-28 16:27:31 -0700470 } else if (inFreeformSpace || (replacing && mWallpaperTarget != null)) {
Wale Ogunwale21fdd912015-08-20 12:34:57 -0700471 // In freeform mode we set the wallpaper as its own target, so we don't need an
Filip Gruszczynski51cb83e2015-11-05 09:32:19 -0800472 // additional window to make it visible. When we are replacing a window and there was
473 // wallpaper before replacement, we want to keep the window until the new windows fully
474 // appear and can determine the visibility, to avoid flickering.
Wale Ogunwale21fdd912015-08-20 12:34:57 -0700475 result.setWallpaperTarget(result.topWallpaper, result.topWallpaperIndex);
Wale Ogunwale6cbba702016-06-28 16:27:31 -0700476
Jorim Jaggife762342016-10-13 14:33:27 +0200477 } else if (keyguardGoingAwayWithWallpaper || needsShowWhenLockedWallpaper) {
478 // Keep the wallpaper during Keyguard exit but also when it's needed for a
479 // non-fullscreen show when locked activity.
Wale Ogunwale6cbba702016-06-28 16:27:31 -0700480 result.setWallpaperTarget(result.topWallpaper, result.topWallpaperIndex);
Wale Ogunwale21fdd912015-08-20 12:34:57 -0700481 }
Wale Ogunwale5f61d042015-08-20 10:09:47 -0700482 }
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700483
Jorim Jaggife762342016-10-13 14:33:27 +0200484 private boolean isFullscreen(WindowManager.LayoutParams attrs) {
485 return attrs.x == 0 && attrs.y == 0
486 && attrs.width == WindowManager.LayoutParams.MATCH_PARENT
487 && attrs.height == WindowManager.LayoutParams.MATCH_PARENT;
488 }
489
Wale Ogunwale0c4a40ef2016-10-07 07:06:40 -0700490 /** Updates the target wallpaper if needed and returns true if an update happened. */
Wale Ogunwale5f61d042015-08-20 10:09:47 -0700491 private boolean updateWallpaperWindowsTarget(
Wale Ogunwalef7cab102016-10-25 15:25:14 -0700492 ReadOnlyWindowList windows, FindWallpaperTargetResult result) {
Wale Ogunwale5f61d042015-08-20 10:09:47 -0700493
Wale Ogunwale5f61d042015-08-20 10:09:47 -0700494 WindowState wallpaperTarget = result.wallpaperTarget;
495 int wallpaperTargetIndex = result.wallpaperTargetIndex;
496
Wale Ogunwale0c4a40ef2016-10-07 07:06:40 -0700497 if (mWallpaperTarget == wallpaperTarget
498 || (mLowerWallpaperTarget != null && mLowerWallpaperTarget == wallpaperTarget)) {
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700499
Wale Ogunwale0c4a40ef2016-10-07 07:06:40 -0700500 if (mLowerWallpaperTarget != null) {
501 // Is it time to stop animating?
502 if (!mLowerWallpaperTarget.isAnimatingLw()
503 || !mUpperWallpaperTarget.isAnimatingLw()) {
Wale Ogunwale5f61d042015-08-20 10:09:47 -0700504 if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
Wale Ogunwale0c4a40ef2016-10-07 07:06:40 -0700505 "No longer animating wallpaper targets!");
506 mLowerWallpaperTarget = null;
507 mUpperWallpaperTarget = null;
508 mWallpaperTarget = wallpaperTarget;
509 return true;
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700510 }
511 }
512
Wale Ogunwale0c4a40ef2016-10-07 07:06:40 -0700513 return false;
514 }
515
516 if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
517 "New wallpaper target: " + wallpaperTarget + " oldTarget: " + mWallpaperTarget);
518
519 mLowerWallpaperTarget = null;
520 mUpperWallpaperTarget = null;
521
522 WindowState oldW = mWallpaperTarget;
523 mWallpaperTarget = wallpaperTarget;
524
525 if (wallpaperTarget == null || oldW == null) {
526 return true;
527 }
528
529 // Now what is happening... if the current and new targets are animating,
530 // then we are in our super special mode!
531 boolean oldAnim = oldW.isAnimatingLw();
532 boolean foundAnim = wallpaperTarget.isAnimatingLw();
533 if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
534 "New animation: " + foundAnim + " old animation: " + oldAnim);
535
536 if (!foundAnim || !oldAnim) {
537 return true;
538 }
539
540 int oldI = windows.indexOf(oldW);
541 if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG,
542 "New i: " + wallpaperTargetIndex + " old i: " + oldI);
543
544 if (oldI < 0) {
545 return true;
546 }
547
548 final boolean newTargetHidden = wallpaperTarget.mAppToken != null
549 && wallpaperTarget.mAppToken.hiddenRequested;
550 final boolean oldTargetHidden = oldW.mAppToken != null
551 && oldW.mAppToken.hiddenRequested;
552
553 if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG, "Animating wallpapers:" + " old#" + oldI + "="
554 + oldW + " hidden=" + oldTargetHidden + " new#" + wallpaperTargetIndex + "="
555 + wallpaperTarget + " hidden=" + newTargetHidden);
556
557 // Set the upper and lower wallpaper targets correctly,
558 // and make sure that we are positioning the wallpaper below the lower.
559 if (wallpaperTargetIndex > oldI) {
560 // The new target is on top of the old one.
561 if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG, "Found target above old target.");
562 mUpperWallpaperTarget = wallpaperTarget;
563 mLowerWallpaperTarget = oldW;
564
565 wallpaperTarget = oldW;
566 wallpaperTargetIndex = oldI;
567 } else {
568 // The new target is below the old one.
569 if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG, "Found target below old target.");
570 mUpperWallpaperTarget = oldW;
571 mLowerWallpaperTarget = wallpaperTarget;
572 }
573
574 if (newTargetHidden && !oldTargetHidden) {
575 if (DEBUG_WALLPAPER_LIGHT) Slog.v(TAG, "Old wallpaper still the target.");
576 // Use the old target if new target is hidden but old target
577 // is not. If they're both hidden, still use the new target.
578 mWallpaperTarget = oldW;
579 } else if (newTargetHidden == oldTargetHidden
580 && !mService.mOpeningApps.contains(wallpaperTarget.mAppToken)
581 && (mService.mOpeningApps.contains(oldW.mAppToken)
582 || mService.mClosingApps.contains(oldW.mAppToken))) {
583 // If they're both hidden (or both not hidden), prefer the one that's currently in
584 // opening or closing app list, this allows transition selection logic to better
585 // determine the wallpaper status of opening/closing apps.
586 mWallpaperTarget = oldW;
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700587 }
588
Wale Ogunwale5f61d042015-08-20 10:09:47 -0700589 result.setWallpaperTarget(wallpaperTarget, wallpaperTargetIndex);
Wale Ogunwale0c4a40ef2016-10-07 07:06:40 -0700590 return true;
Wale Ogunwale5f61d042015-08-20 10:09:47 -0700591 }
592
Wale Ogunwalef7cab102016-10-25 15:25:14 -0700593 private boolean updateWallpaperWindowsTargetByLayer(ReadOnlyWindowList windows,
Wale Ogunwale0c4a40ef2016-10-07 07:06:40 -0700594 FindWallpaperTargetResult result) {
Wale Ogunwale5f61d042015-08-20 10:09:47 -0700595
596 WindowState wallpaperTarget = result.wallpaperTarget;
597 int wallpaperTargetIndex = result.wallpaperTargetIndex;
598 boolean visible = wallpaperTarget != null;
599
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700600 if (visible) {
Wale Ogunwale5f61d042015-08-20 10:09:47 -0700601 // The window is visible to the compositor...but is it visible to the user?
602 // That is what the wallpaper cares about.
603 visible = isWallpaperVisible(wallpaperTarget);
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700604 if (DEBUG_WALLPAPER) Slog.v(TAG, "Wallpaper visibility: " + visible);
605
Wale Ogunwale5f61d042015-08-20 10:09:47 -0700606 // If the wallpaper target is animating, we may need to copy its layer adjustment.
607 // Only do this if we are not transferring between two wallpaper targets.
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700608 mWallpaperAnimLayerAdjustment =
Wale Ogunwale5f61d042015-08-20 10:09:47 -0700609 (mLowerWallpaperTarget == null && wallpaperTarget.mAppToken != null)
610 ? wallpaperTarget.mAppToken.mAppAnimator.animLayerAdjustment : 0;
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700611
612 final int maxLayer = (mService.mPolicy.getMaxWallpaperLayer() * TYPE_LAYER_MULTIPLIER)
613 + TYPE_LAYER_OFFSET;
614
615 // Now w is the window we are supposed to be behind... but we
616 // need to be sure to also be behind any of its attached windows,
617 // AND any starting window associated with it, AND below the
618 // maximum layer the policy allows for wallpapers.
Wale Ogunwale5f61d042015-08-20 10:09:47 -0700619 while (wallpaperTargetIndex > 0) {
Wale Ogunwalecaa53af2016-07-17 14:50:26 -0700620 final WindowState wb = windows.get(wallpaperTargetIndex - 1);
621 final WindowState wbParentWindow = wb.getParentWindow();
622 final WindowState wallpaperParentWindow = wallpaperTarget.getParentWindow();
623 if (wb.mBaseLayer < maxLayer
624 && wbParentWindow != wallpaperTarget
625 && (wallpaperParentWindow == null || wbParentWindow != wallpaperParentWindow)
626 && (wb.mAttrs.type != TYPE_APPLICATION_STARTING
Wale Ogunwale5f61d042015-08-20 10:09:47 -0700627 || wallpaperTarget.mToken == null
628 || wb.mToken != wallpaperTarget.mToken)) {
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700629 // This window is not related to the previous one in any
630 // interesting way, so stop here.
631 break;
632 }
Wale Ogunwale5f61d042015-08-20 10:09:47 -0700633 wallpaperTarget = wb;
634 wallpaperTargetIndex--;
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700635 }
636 } else {
637 if (DEBUG_WALLPAPER) Slog.v(TAG, "No wallpaper target");
638 }
639
Wale Ogunwale5f61d042015-08-20 10:09:47 -0700640 result.setWallpaperTarget(wallpaperTarget, wallpaperTargetIndex);
641 return visible;
642 }
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700643
Wale Ogunwalef7cab102016-10-25 15:25:14 -0700644 private boolean updateWallpaperWindowsPlacement(ReadOnlyWindowList windows,
Wale Ogunwale5f61d042015-08-20 10:09:47 -0700645 WindowState wallpaperTarget, int wallpaperTargetIndex, boolean visible) {
646
647 // TODO(multidisplay): Wallpapers on main screen only.
648 final DisplayInfo displayInfo = mService.getDefaultDisplayContentLocked().getDisplayInfo();
649 final int dw = displayInfo.logicalWidth;
650 final int dh = displayInfo.logicalHeight;
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700651
Wale Ogunwalee4da0c12016-07-29 12:47:02 -0700652 // Start stepping backwards from here, ensuring that our wallpaper windows are correctly placed.
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700653 boolean changed = false;
654 for (int curTokenNdx = mWallpaperTokens.size() - 1; curTokenNdx >= 0; curTokenNdx--) {
Wale Ogunwalee4da0c12016-07-29 12:47:02 -0700655 final WindowToken token = mWallpaperTokens.get(curTokenNdx);
656 changed |= token.updateWallpaperWindowsPlacement(windows, wallpaperTarget,
657 wallpaperTargetIndex, visible, dw, dh, mWallpaperAnimLayerAdjustment);
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700658 }
659
Wale Ogunwale5f61d042015-08-20 10:09:47 -0700660 return changed;
661 }
662
Wale Ogunwalef7cab102016-10-25 15:25:14 -0700663 boolean adjustWallpaperWindows(ReadOnlyWindowList windows) {
Wale Ogunwalee05f5012016-09-16 16:27:29 -0700664 mService.mRoot.mWallpaperMayChange = false;
Wale Ogunwale5f61d042015-08-20 10:09:47 -0700665
Wale Ogunwale5f61d042015-08-20 10:09:47 -0700666 // First find top-most window that has asked to be on top of the wallpaper;
667 // all wallpapers go behind it.
668 findWallpaperTarget(windows, mFindResults);
669 final boolean targetChanged = updateWallpaperWindowsTarget(windows, mFindResults);
670 final boolean visible = updateWallpaperWindowsTargetByLayer(windows, mFindResults);
671 WindowState wallpaperTarget = mFindResults.wallpaperTarget;
672 int wallpaperTargetIndex = mFindResults.wallpaperTargetIndex;
673
674 if (wallpaperTarget == null && mFindResults.topWallpaper != null) {
675 // There is no wallpaper target, so it goes at the bottom.
676 // We will assume it is the same place as last time, if known.
677 wallpaperTarget = mFindResults.topWallpaper;
678 wallpaperTargetIndex = mFindResults.topWallpaperIndex + 1;
679 } else {
680 // Okay i is the position immediately above the wallpaper.
681 // Look at what is below it for later.
682 wallpaperTarget = wallpaperTargetIndex > 0
683 ? windows.get(wallpaperTargetIndex - 1) : null;
684 }
685
686 if (visible) {
687 if (mWallpaperTarget.mWallpaperX >= 0) {
688 mLastWallpaperX = mWallpaperTarget.mWallpaperX;
689 mLastWallpaperXStep = mWallpaperTarget.mWallpaperXStep;
690 }
691 if (mWallpaperTarget.mWallpaperY >= 0) {
692 mLastWallpaperY = mWallpaperTarget.mWallpaperY;
693 mLastWallpaperYStep = mWallpaperTarget.mWallpaperYStep;
694 }
695 if (mWallpaperTarget.mWallpaperDisplayOffsetX != Integer.MIN_VALUE) {
696 mLastWallpaperDisplayOffsetX = mWallpaperTarget.mWallpaperDisplayOffsetX;
697 }
698 if (mWallpaperTarget.mWallpaperDisplayOffsetY != Integer.MIN_VALUE) {
699 mLastWallpaperDisplayOffsetY = mWallpaperTarget.mWallpaperDisplayOffsetY;
700 }
701 }
702
703 final boolean changed = updateWallpaperWindowsPlacement(
704 windows, wallpaperTarget, wallpaperTargetIndex, visible);
705
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700706 if (targetChanged && DEBUG_WALLPAPER_LIGHT) Slog.d(TAG, "New wallpaper: target="
707 + mWallpaperTarget + " lower=" + mLowerWallpaperTarget + " upper="
708 + mUpperWallpaperTarget);
709
710 return changed;
711 }
712
713 boolean processWallpaperDrawPendingTimeout() {
714 if (mWallpaperDrawState == WALLPAPER_DRAW_PENDING) {
715 mWallpaperDrawState = WALLPAPER_DRAW_TIMEOUT;
716 if (DEBUG_APP_TRANSITIONS || DEBUG_WALLPAPER) Slog.v(TAG,
717 "*** WALLPAPER DRAW TIMEOUT");
718 return true;
719 }
720 return false;
721 }
722
723 boolean wallpaperTransitionReady() {
724 boolean transitionReady = true;
725 boolean wallpaperReady = true;
726 for (int curTokenIndex = mWallpaperTokens.size() - 1;
727 curTokenIndex >= 0 && wallpaperReady; curTokenIndex--) {
Wale Ogunwalee4da0c12016-07-29 12:47:02 -0700728 final WindowToken token = mWallpaperTokens.get(curTokenIndex);
729 if (token.hasVisibleNotDrawnWallpaper()) {
730 // We've told this wallpaper to be visible, but it is not drawn yet
731 wallpaperReady = false;
732 if (mWallpaperDrawState != WALLPAPER_DRAW_TIMEOUT) {
733 // wait for this wallpaper until it is drawn or timeout
734 transitionReady = false;
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700735 }
Wale Ogunwalee4da0c12016-07-29 12:47:02 -0700736 if (mWallpaperDrawState == WALLPAPER_DRAW_NORMAL) {
737 mWallpaperDrawState = WALLPAPER_DRAW_PENDING;
738 mService.mH.removeMessages(WALLPAPER_DRAW_PENDING_TIMEOUT);
739 mService.mH.sendEmptyMessageDelayed(WALLPAPER_DRAW_PENDING_TIMEOUT,
740 WALLPAPER_DRAW_PENDING_TIMEOUT_DURATION);
741 }
742 if (DEBUG_APP_TRANSITIONS || DEBUG_WALLPAPER) Slog.v(TAG,
743 "Wallpaper should be visible but has not been drawn yet. " +
744 "mWallpaperDrawState=" + mWallpaperDrawState);
745 break;
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700746 }
747 }
748 if (wallpaperReady) {
749 mWallpaperDrawState = WALLPAPER_DRAW_NORMAL;
750 mService.mH.removeMessages(WALLPAPER_DRAW_PENDING_TIMEOUT);
751 }
752
753 return transitionReady;
754 }
755
Wale Ogunwale0c4a40ef2016-10-07 07:06:40 -0700756 /**
757 * Adjusts the wallpaper windows if the input display has a pending wallpaper layout or one of
758 * the opening apps should be a wallpaper target.
759 */
Wale Ogunwale0303c572016-10-20 10:16:29 -0700760 void adjustWallpaperWindowsForAppTransitionIfNeeded(DisplayContent dc,
761 ArraySet<AppWindowToken> openingApps) {
Wale Ogunwale0c4a40ef2016-10-07 07:06:40 -0700762 boolean adjust = false;
763 if ((dc.pendingLayoutChanges & FINISH_LAYOUT_REDO_WALLPAPER) != 0) {
764 adjust = true;
765 } else {
766 for (int i = openingApps.size() - 1; i >= 0; --i) {
767 final AppWindowToken token = openingApps.valueAt(i);
768 if (token.windowsCanBeWallpaperTarget()) {
769 adjust = true;
770 break;
771 }
772 }
773 }
774
Wale Ogunwale0303c572016-10-20 10:16:29 -0700775 if (adjust) {
776 dc.adjustWallpaperWindows();
Wale Ogunwale0c4a40ef2016-10-07 07:06:40 -0700777 }
778 }
779
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700780 void addWallpaperToken(WindowToken token) {
781 mWallpaperTokens.add(token);
782 }
783
784 void removeWallpaperToken(WindowToken token) {
785 mWallpaperTokens.remove(token);
786 }
787
788 void dump(PrintWriter pw, String prefix) {
789 pw.print(prefix); pw.print("mWallpaperTarget="); pw.println(mWallpaperTarget);
790 if (mLowerWallpaperTarget != null || mUpperWallpaperTarget != null) {
791 pw.print(prefix); pw.print("mLowerWallpaperTarget="); pw.println(mLowerWallpaperTarget);
792 pw.print(prefix); pw.print("mUpperWallpaperTarget="); pw.println(mUpperWallpaperTarget);
793 }
794 pw.print(prefix); pw.print("mLastWallpaperX="); pw.print(mLastWallpaperX);
795 pw.print(" mLastWallpaperY="); pw.println(mLastWallpaperY);
796 if (mLastWallpaperDisplayOffsetX != Integer.MIN_VALUE
797 || mLastWallpaperDisplayOffsetY != Integer.MIN_VALUE) {
798 pw.print(prefix);
799 pw.print("mLastWallpaperDisplayOffsetX="); pw.print(mLastWallpaperDisplayOffsetX);
800 pw.print(" mLastWallpaperDisplayOffsetY="); pw.println(mLastWallpaperDisplayOffsetY);
801 }
Wale Ogunwalec69694a2016-10-18 13:51:15 -0700802
803 if (mWallpaperAnimLayerAdjustment != 0) {
804 pw.println(prefix + "mWallpaperAnimLayerAdjustment=" + mWallpaperAnimLayerAdjustment);
805 }
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700806 }
807
808 void dumpTokens(PrintWriter pw, String prefix, boolean dumpAll) {
809 if (!mWallpaperTokens.isEmpty()) {
810 pw.println();
811 pw.print(prefix); pw.println("Wallpaper tokens:");
812 for (int i = mWallpaperTokens.size() - 1; i >= 0; i--) {
813 WindowToken token = mWallpaperTokens.get(i);
814 pw.print(prefix); pw.print("Wallpaper #"); pw.print(i);
815 pw.print(' '); pw.print(token);
816 if (dumpAll) {
817 pw.println(':');
818 token.dump(pw, " ");
819 } else {
820 pw.println();
821 }
822 }
823 }
824 }
Wale Ogunwale5f61d042015-08-20 10:09:47 -0700825
826 /** Helper class for storing the results of a wallpaper target find operation. */
827 final private static class FindWallpaperTargetResult {
828 int topWallpaperIndex = 0;
829 WindowState topWallpaper = null;
830 int wallpaperTargetIndex = 0;
831 WindowState wallpaperTarget = null;
832
833 void setTopWallpaper(WindowState win, int index) {
834 topWallpaper = win;
835 topWallpaperIndex = index;
836 }
837
838 void setWallpaperTarget(WindowState win, int index) {
839 wallpaperTarget = win;
840 wallpaperTargetIndex = index;
841 }
842
843 void reset() {
844 topWallpaperIndex = 0;
845 topWallpaper = null;
846 wallpaperTargetIndex = 0;
847 wallpaperTarget = null;
848 }
849 }
Wale Ogunwalee8069dc2015-08-18 09:52:01 -0700850}