blob: 72049ec4b28eeea9d8bfaabcef9e030ae4b3b37f [file] [log] [blame]
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001/*
2 * Copyright (C) 2011 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
19import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW;
20import static android.view.WindowManager.LayoutParams.FLAG_COMPATIBLE_WINDOW;
21import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS;
22import static android.view.WindowManager.LayoutParams.LAST_SUB_WINDOW;
23import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
24import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
25import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG;
26import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
27
28import com.android.server.wm.WindowManagerService.H;
29
30import android.content.res.Configuration;
31import android.graphics.Matrix;
32import android.graphics.PixelFormat;
33import android.graphics.Rect;
34import android.graphics.Region;
35import android.os.IBinder;
36import android.os.RemoteException;
37import android.util.Slog;
38import android.view.Gravity;
39import android.view.IApplicationToken;
40import android.view.IWindow;
41import android.view.InputChannel;
42import android.view.Surface;
43import android.view.View;
44import android.view.ViewTreeObserver;
45import android.view.WindowManager;
46import android.view.WindowManagerPolicy;
47import android.view.WindowManager.LayoutParams;
48import android.view.animation.Animation;
49import android.view.animation.Transformation;
50
51import java.io.PrintWriter;
52import java.util.ArrayList;
53
54/**
55 * A window in the window manager.
56 */
57final class WindowState implements WindowManagerPolicy.WindowState {
58 final WindowManagerService mService;
59 final Session mSession;
60 final IWindow mClient;
61 WindowToken mToken;
62 WindowToken mRootToken;
63 AppWindowToken mAppToken;
64 AppWindowToken mTargetAppToken;
65 final WindowManager.LayoutParams mAttrs = new WindowManager.LayoutParams();
66 final DeathRecipient mDeathRecipient;
67 final WindowState mAttachedWindow;
68 final ArrayList<WindowState> mChildWindows = new ArrayList<WindowState>();
69 final int mBaseLayer;
70 final int mSubLayer;
71 final boolean mLayoutAttached;
72 final boolean mIsImWindow;
73 final boolean mIsWallpaper;
74 final boolean mIsFloatingLayer;
Dianne Hackborne2515ee2011-04-27 18:52:56 -040075 final boolean mEnforceSizeCompat;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080076 int mViewVisibility;
77 boolean mPolicyVisibility = true;
78 boolean mPolicyVisibilityAfterAnim = true;
79 boolean mAppFreezing;
80 Surface mSurface;
81 boolean mReportDestroySurface;
82 boolean mSurfacePendingDestroy;
83 boolean mAttachedHidden; // is our parent window hidden?
84 boolean mLastHidden; // was this window last hidden?
85 boolean mWallpaperVisible; // for wallpaper, what was last vis report?
86 int mRequestedWidth;
87 int mRequestedHeight;
88 int mLastRequestedWidth;
89 int mLastRequestedHeight;
90 int mLayer;
91 int mAnimLayer;
92 int mLastLayer;
93 boolean mHaveFrame;
94 boolean mObscured;
Dianne Hackborne2515ee2011-04-27 18:52:56 -040095 boolean mNeedsBackgroundFiller;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -080096 boolean mTurnOnScreen;
97
98 int mLayoutSeq = -1;
99
100 Configuration mConfiguration = null;
101
102 // Actual frame shown on-screen (may be modified by animation)
103 final Rect mShownFrame = new Rect();
104 final Rect mLastShownFrame = new Rect();
105
106 /**
107 * Set when we have changed the size of the surface, to know that
108 * we must tell them application to resize (and thus redraw itself).
109 */
110 boolean mSurfaceResized;
111
112 /**
113 * Insets that determine the actually visible area
114 */
115 final Rect mVisibleInsets = new Rect();
116 final Rect mLastVisibleInsets = new Rect();
117 boolean mVisibleInsetsChanged;
118
119 /**
120 * Insets that are covered by system windows
121 */
122 final Rect mContentInsets = new Rect();
123 final Rect mLastContentInsets = new Rect();
124 boolean mContentInsetsChanged;
125
126 /**
127 * Set to true if we are waiting for this window to receive its
128 * given internal insets before laying out other windows based on it.
129 */
130 boolean mGivenInsetsPending;
131
132 /**
133 * These are the content insets that were given during layout for
134 * this window, to be applied to windows behind it.
135 */
136 final Rect mGivenContentInsets = new Rect();
137
138 /**
139 * These are the visible insets that were given during layout for
140 * this window, to be applied to windows behind it.
141 */
142 final Rect mGivenVisibleInsets = new Rect();
143
144 /**
145 * This is the given touchable area relative to the window frame, or null if none.
146 */
147 final Region mGivenTouchableRegion = new Region();
148
149 /**
150 * Flag indicating whether the touchable region should be adjusted by
151 * the visible insets; if false the area outside the visible insets is
152 * NOT touchable, so we must use those to adjust the frame during hit
153 * tests.
154 */
155 int mTouchableInsets = ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME;
156
157 // Current transformation being applied.
158 boolean mHaveMatrix;
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400159 float mGlobalScale=1;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800160 float mDsDx=1, mDtDx=0, mDsDy=0, mDtDy=1;
161 float mLastDsDx=1, mLastDtDx=0, mLastDsDy=0, mLastDtDy=1;
162 float mHScale=1, mVScale=1;
163 float mLastHScale=1, mLastVScale=1;
164 final Matrix mTmpMatrix = new Matrix();
165
166 // "Real" frame that the application sees.
167 final Rect mFrame = new Rect();
168 final Rect mLastFrame = new Rect();
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400169 final Rect mScaledFrame = new Rect();
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800170
171 final Rect mContainingFrame = new Rect();
172 final Rect mDisplayFrame = new Rect();
173 final Rect mContentFrame = new Rect();
174 final Rect mParentFrame = new Rect();
175 final Rect mVisibleFrame = new Rect();
176
177 boolean mContentChanged;
178
179 float mShownAlpha = 1;
180 float mAlpha = 1;
181 float mLastAlpha = 1;
182
183 // Set to true if, when the window gets displayed, it should perform
184 // an enter animation.
185 boolean mEnterAnimationPending;
186
187 // Currently running animation.
188 boolean mAnimating;
189 boolean mLocalAnimating;
190 Animation mAnimation;
191 boolean mAnimationIsEntrance;
192 boolean mHasTransformation;
193 boolean mHasLocalTransformation;
194 final Transformation mTransformation = new Transformation();
195
196 // If a window showing a wallpaper: the requested offset for the
197 // wallpaper; if a wallpaper window: the currently applied offset.
198 float mWallpaperX = -1;
199 float mWallpaperY = -1;
200
201 // If a window showing a wallpaper: what fraction of the offset
202 // range corresponds to a full virtual screen.
203 float mWallpaperXStep = -1;
204 float mWallpaperYStep = -1;
205
206 // Wallpaper windows: pixels offset based on above variables.
207 int mXOffset;
208 int mYOffset;
209
210 // This is set after IWindowSession.relayout() has been called at
211 // least once for the window. It allows us to detect the situation
212 // where we don't yet have a surface, but should have one soon, so
213 // we can give the window focus before waiting for the relayout.
214 boolean mRelayoutCalled;
215
216 // This is set after the Surface has been created but before the
217 // window has been drawn. During this time the surface is hidden.
218 boolean mDrawPending;
219
220 // This is set after the window has finished drawing for the first
221 // time but before its surface is shown. The surface will be
222 // displayed when the next layout is run.
223 boolean mCommitDrawPending;
224
225 // This is set during the time after the window's drawing has been
226 // committed, and before its surface is actually shown. It is used
227 // to delay showing the surface until all windows in a token are ready
228 // to be shown.
229 boolean mReadyToShow;
230
231 // Set when the window has been shown in the screen the first time.
232 boolean mHasDrawn;
233
234 // Currently running an exit animation?
235 boolean mExiting;
236
237 // Currently on the mDestroySurface list?
238 boolean mDestroying;
239
240 // Completely remove from window manager after exit animation?
241 boolean mRemoveOnExit;
242
243 // Set when the orientation is changing and this window has not yet
244 // been updated for the new orientation.
245 boolean mOrientationChanging;
246
247 // Is this window now (or just being) removed?
248 boolean mRemoved;
249
250 // Temp for keeping track of windows that have been removed when
251 // rebuilding window list.
252 boolean mRebuilding;
253
254 // For debugging, this is the last information given to the surface flinger.
255 boolean mSurfaceShown;
256 int mSurfaceX, mSurfaceY, mSurfaceW, mSurfaceH;
257 int mSurfaceLayer;
258 float mSurfaceAlpha;
259
260 // Input channel and input window handle used by the input dispatcher.
261 InputWindowHandle mInputWindowHandle;
262 InputChannel mInputChannel;
263
264 // Used to improve performance of toString()
265 String mStringNameCache;
266 CharSequence mLastTitle;
267 boolean mWasPaused;
268
269 WindowState(WindowManagerService service, Session s, IWindow c, WindowToken token,
270 WindowState attachedWindow, WindowManager.LayoutParams a,
271 int viewVisibility) {
272 mService = service;
273 mSession = s;
274 mClient = c;
275 mToken = token;
276 mAttrs.copyFrom(a);
277 mViewVisibility = viewVisibility;
278 DeathRecipient deathRecipient = new DeathRecipient();
279 mAlpha = a.alpha;
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400280 mEnforceSizeCompat = (mAttrs.flags & FLAG_COMPATIBLE_WINDOW) != 0;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800281 if (WindowManagerService.localLOGV) Slog.v(
282 WindowManagerService.TAG, "Window " + this + " client=" + c.asBinder()
283 + " token=" + token + " (" + mAttrs.token + ")");
284 try {
285 c.asBinder().linkToDeath(deathRecipient, 0);
286 } catch (RemoteException e) {
287 mDeathRecipient = null;
288 mAttachedWindow = null;
289 mLayoutAttached = false;
290 mIsImWindow = false;
291 mIsWallpaper = false;
292 mIsFloatingLayer = false;
293 mBaseLayer = 0;
294 mSubLayer = 0;
295 return;
296 }
297 mDeathRecipient = deathRecipient;
298
299 if ((mAttrs.type >= FIRST_SUB_WINDOW &&
300 mAttrs.type <= LAST_SUB_WINDOW)) {
301 // The multiplier here is to reserve space for multiple
302 // windows in the same type layer.
303 mBaseLayer = mService.mPolicy.windowTypeToLayerLw(
304 attachedWindow.mAttrs.type) * WindowManagerService.TYPE_LAYER_MULTIPLIER
305 + WindowManagerService.TYPE_LAYER_OFFSET;
306 mSubLayer = mService.mPolicy.subWindowTypeToLayerLw(a.type);
307 mAttachedWindow = attachedWindow;
308 if (WindowManagerService.DEBUG_ADD_REMOVE) Slog.v(WindowManagerService.TAG, "Adding " + this + " to " + mAttachedWindow);
309 mAttachedWindow.mChildWindows.add(this);
310 mLayoutAttached = mAttrs.type !=
311 WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
312 mIsImWindow = attachedWindow.mAttrs.type == TYPE_INPUT_METHOD
313 || attachedWindow.mAttrs.type == TYPE_INPUT_METHOD_DIALOG;
314 mIsWallpaper = attachedWindow.mAttrs.type == TYPE_WALLPAPER;
315 mIsFloatingLayer = mIsImWindow || mIsWallpaper;
316 } else {
317 // The multiplier here is to reserve space for multiple
318 // windows in the same type layer.
319 mBaseLayer = mService.mPolicy.windowTypeToLayerLw(a.type)
320 * WindowManagerService.TYPE_LAYER_MULTIPLIER
321 + WindowManagerService.TYPE_LAYER_OFFSET;
322 mSubLayer = 0;
323 mAttachedWindow = null;
324 mLayoutAttached = false;
325 mIsImWindow = mAttrs.type == TYPE_INPUT_METHOD
326 || mAttrs.type == TYPE_INPUT_METHOD_DIALOG;
327 mIsWallpaper = mAttrs.type == TYPE_WALLPAPER;
328 mIsFloatingLayer = mIsImWindow || mIsWallpaper;
329 }
330
331 WindowState appWin = this;
332 while (appWin.mAttachedWindow != null) {
333 appWin = mAttachedWindow;
334 }
335 WindowToken appToken = appWin.mToken;
336 while (appToken.appWindowToken == null) {
337 WindowToken parent = mService.mTokenMap.get(appToken.token);
338 if (parent == null || appToken == parent) {
339 break;
340 }
341 appToken = parent;
342 }
343 mRootToken = appToken;
344 mAppToken = appToken.appWindowToken;
345
346 mSurface = null;
347 mRequestedWidth = 0;
348 mRequestedHeight = 0;
349 mLastRequestedWidth = 0;
350 mLastRequestedHeight = 0;
351 mXOffset = 0;
352 mYOffset = 0;
353 mLayer = 0;
354 mAnimLayer = 0;
355 mLastLayer = 0;
356 mInputWindowHandle = new InputWindowHandle(
357 mAppToken != null ? mAppToken.mInputApplicationHandle : null, this);
358 }
359
360 void attach() {
361 if (WindowManagerService.localLOGV) Slog.v(
362 WindowManagerService.TAG, "Attaching " + this + " token=" + mToken
363 + ", list=" + mToken.windows);
364 mSession.windowAddedLocked();
365 }
366
367 public void computeFrameLw(Rect pf, Rect df, Rect cf, Rect vf) {
368 mHaveFrame = true;
369
370 final Rect container = mContainingFrame;
371 container.set(pf);
372
373 final Rect display = mDisplayFrame;
374 display.set(df);
375
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400376 if (mEnforceSizeCompat) {
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800377 container.intersect(mService.mCompatibleScreenFrame);
378 if ((mAttrs.flags & FLAG_LAYOUT_NO_LIMITS) == 0) {
379 display.intersect(mService.mCompatibleScreenFrame);
380 }
381 }
382
383 final int pw = container.right - container.left;
384 final int ph = container.bottom - container.top;
385
386 int w,h;
387 if ((mAttrs.flags & mAttrs.FLAG_SCALED) != 0) {
388 w = mAttrs.width < 0 ? pw : mAttrs.width;
389 h = mAttrs.height< 0 ? ph : mAttrs.height;
390 } else {
391 w = mAttrs.width == mAttrs.MATCH_PARENT ? pw : mRequestedWidth;
392 h = mAttrs.height== mAttrs.MATCH_PARENT ? ph : mRequestedHeight;
393 }
394
395 if (!mParentFrame.equals(pf)) {
396 //Slog.i(TAG, "Window " + this + " content frame from " + mParentFrame
397 // + " to " + pf);
398 mParentFrame.set(pf);
399 mContentChanged = true;
400 }
401
402 final Rect content = mContentFrame;
403 content.set(cf);
404
405 final Rect visible = mVisibleFrame;
406 visible.set(vf);
407
408 final Rect frame = mFrame;
409 final int fw = frame.width();
410 final int fh = frame.height();
411
412 //System.out.println("In: w=" + w + " h=" + h + " container=" +
413 // container + " x=" + mAttrs.x + " y=" + mAttrs.y);
414
415 Gravity.apply(mAttrs.gravity, w, h, container,
416 (int) (mAttrs.x + mAttrs.horizontalMargin * pw),
417 (int) (mAttrs.y + mAttrs.verticalMargin * ph), frame);
418
419 //System.out.println("Out: " + mFrame);
420
421 // Now make sure the window fits in the overall display.
422 Gravity.applyDisplay(mAttrs.gravity, df, frame);
423
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400424 int adjRight=0, adjBottom=0;
425
426 if (mEnforceSizeCompat) {
427 // Adjust window offsets by the scaling factor.
428 int xoff = (int)((frame.left-mService.mCompatibleScreenFrame.left)*mGlobalScale)
429 - (frame.left-mService.mCompatibleScreenFrame.left);
430 int yoff = (int)((frame.top-mService.mCompatibleScreenFrame.top)*mGlobalScale)
431 - (frame.top-mService.mCompatibleScreenFrame.top);
432 frame.offset(xoff, yoff);
433
434 // We are temporarily going to apply the compatibility scale
435 // to the window so that we can correctly associate it with the
436 // content and visible frame.
437 adjRight = frame.right - frame.left;
438 adjRight = (int)((adjRight)*mGlobalScale + .5f) - adjRight;
439 adjBottom = frame.bottom - frame.top;
440 adjBottom = (int)((adjBottom)*mGlobalScale + .5f) - adjBottom;
441 frame.right += adjRight;
442 frame.bottom += adjBottom;
443 }
444 mScaledFrame.set(frame);
445
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800446 // Make sure the content and visible frames are inside of the
447 // final window frame.
448 if (content.left < frame.left) content.left = frame.left;
449 if (content.top < frame.top) content.top = frame.top;
450 if (content.right > frame.right) content.right = frame.right;
451 if (content.bottom > frame.bottom) content.bottom = frame.bottom;
452 if (visible.left < frame.left) visible.left = frame.left;
453 if (visible.top < frame.top) visible.top = frame.top;
454 if (visible.right > frame.right) visible.right = frame.right;
455 if (visible.bottom > frame.bottom) visible.bottom = frame.bottom;
456
457 final Rect contentInsets = mContentInsets;
458 contentInsets.left = content.left-frame.left;
459 contentInsets.top = content.top-frame.top;
460 contentInsets.right = frame.right-content.right;
461 contentInsets.bottom = frame.bottom-content.bottom;
462
463 final Rect visibleInsets = mVisibleInsets;
464 visibleInsets.left = visible.left-frame.left;
465 visibleInsets.top = visible.top-frame.top;
466 visibleInsets.right = frame.right-visible.right;
467 visibleInsets.bottom = frame.bottom-visible.bottom;
468
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400469 if (mEnforceSizeCompat) {
470 // Scale the computed insets back to the window's compatibility
471 // coordinate space, and put frame back to correct size.
472 final float invScale = 1.0f/mGlobalScale;
473 contentInsets.left = (int)(contentInsets.left*invScale);
474 contentInsets.top = (int)(contentInsets.top*invScale);
475 contentInsets.right = (int)(contentInsets.right*invScale);
476 contentInsets.bottom = (int)(contentInsets.bottom*invScale);
477 visibleInsets.left = (int)(visibleInsets.left*invScale);
478 visibleInsets.top = (int)(visibleInsets.top*invScale);
479 visibleInsets.right = (int)(visibleInsets.right*invScale);
480 visibleInsets.bottom = (int)(visibleInsets.bottom*invScale);
481 frame.right -= adjRight;
482 frame.bottom -= adjBottom;
483 }
484
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800485 if (mIsWallpaper && (fw != frame.width() || fh != frame.height())) {
486 mService.updateWallpaperOffsetLocked(this, mService.mDisplay.getWidth(),
487 mService.mDisplay.getHeight(), false);
488 }
489
490 if (WindowManagerService.localLOGV) {
491 //if ("com.google.android.youtube".equals(mAttrs.packageName)
492 // && mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_PANEL) {
493 Slog.v(WindowManagerService.TAG, "Resolving (mRequestedWidth="
494 + mRequestedWidth + ", mRequestedheight="
495 + mRequestedHeight + ") to" + " (pw=" + pw + ", ph=" + ph
496 + "): frame=" + mFrame.toShortString()
497 + " ci=" + contentInsets.toShortString()
498 + " vi=" + visibleInsets.toShortString());
499 //}
500 }
501 }
502
503 public Rect getFrameLw() {
504 return mFrame;
505 }
506
507 public Rect getShownFrameLw() {
508 return mShownFrame;
509 }
510
511 public Rect getDisplayFrameLw() {
512 return mDisplayFrame;
513 }
514
515 public Rect getContentFrameLw() {
516 return mContentFrame;
517 }
518
519 public Rect getVisibleFrameLw() {
520 return mVisibleFrame;
521 }
522
523 public boolean getGivenInsetsPendingLw() {
524 return mGivenInsetsPending;
525 }
526
527 public Rect getGivenContentInsetsLw() {
528 return mGivenContentInsets;
529 }
530
531 public Rect getGivenVisibleInsetsLw() {
532 return mGivenVisibleInsets;
533 }
534
535 public WindowManager.LayoutParams getAttrs() {
536 return mAttrs;
537 }
538
539 public int getSurfaceLayer() {
540 return mLayer;
541 }
542
543 public IApplicationToken getAppToken() {
544 return mAppToken != null ? mAppToken.appToken : null;
545 }
546
547 public long getInputDispatchingTimeoutNanos() {
548 return mAppToken != null
549 ? mAppToken.inputDispatchingTimeoutNanos
550 : WindowManagerService.DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS;
551 }
552
553 public boolean hasAppShownWindows() {
554 return mAppToken != null ? mAppToken.firstWindowDrawn : false;
555 }
556
557 public void setAnimation(Animation anim) {
558 if (WindowManagerService.localLOGV) Slog.v(
559 WindowManagerService.TAG, "Setting animation in " + this + ": " + anim);
560 mAnimating = false;
561 mLocalAnimating = false;
562 mAnimation = anim;
563 mAnimation.restrictDuration(WindowManagerService.MAX_ANIMATION_DURATION);
564 mAnimation.scaleCurrentDuration(mService.mWindowAnimationScale);
565 }
566
567 public void clearAnimation() {
568 if (mAnimation != null) {
569 mAnimating = true;
570 mLocalAnimating = false;
571 mAnimation.cancel();
572 mAnimation = null;
573 }
574 }
575
576 Surface createSurfaceLocked() {
577 if (mSurface == null) {
578 mReportDestroySurface = false;
579 mSurfacePendingDestroy = false;
580 mDrawPending = true;
581 mCommitDrawPending = false;
582 mReadyToShow = false;
583 if (mAppToken != null) {
584 mAppToken.allDrawn = false;
585 }
586
587 int flags = 0;
588
589 if ((mAttrs.flags&WindowManager.LayoutParams.FLAG_SECURE) != 0) {
590 flags |= Surface.SECURE;
591 }
592 if (WindowManagerService.DEBUG_VISIBILITY) Slog.v(
593 WindowManagerService.TAG, "Creating surface in session "
594 + mSession.mSurfaceSession + " window " + this
595 + " w=" + mFrame.width()
596 + " h=" + mFrame.height() + " format="
597 + mAttrs.format + " flags=" + flags);
598
599 int w = mFrame.width();
600 int h = mFrame.height();
601 if ((mAttrs.flags & LayoutParams.FLAG_SCALED) != 0) {
602 // for a scaled surface, we always want the requested
603 // size.
604 w = mRequestedWidth;
605 h = mRequestedHeight;
606 }
607
608 // Something is wrong and SurfaceFlinger will not like this,
609 // try to revert to sane values
610 if (w <= 0) w = 1;
611 if (h <= 0) h = 1;
612
613 mSurfaceShown = false;
614 mSurfaceLayer = 0;
615 mSurfaceAlpha = 1;
616 mSurfaceX = 0;
617 mSurfaceY = 0;
618 mSurfaceW = w;
619 mSurfaceH = h;
620 try {
621 final boolean isHwAccelerated = (mAttrs.flags &
622 WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED) != 0;
623 final int format = isHwAccelerated ? PixelFormat.TRANSLUCENT : mAttrs.format;
624 if (isHwAccelerated && mAttrs.format == PixelFormat.OPAQUE) {
625 flags |= Surface.OPAQUE;
626 }
627 mSurface = new Surface(
628 mSession.mSurfaceSession, mSession.mPid,
629 mAttrs.getTitle().toString(),
630 0, w, h, format, flags);
631 if (WindowManagerService.SHOW_TRANSACTIONS) Slog.i(WindowManagerService.TAG, " CREATE SURFACE "
632 + mSurface + " IN SESSION "
633 + mSession.mSurfaceSession
634 + ": pid=" + mSession.mPid + " format="
635 + mAttrs.format + " flags=0x"
636 + Integer.toHexString(flags)
637 + " / " + this);
638 } catch (Surface.OutOfResourcesException e) {
639 Slog.w(WindowManagerService.TAG, "OutOfResourcesException creating surface");
Dianne Hackborn64825172011-03-02 21:32:58 -0800640 mService.reclaimSomeSurfaceMemoryLocked(this, "create", true);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800641 return null;
642 } catch (Exception e) {
643 Slog.e(WindowManagerService.TAG, "Exception creating surface", e);
644 return null;
645 }
646
647 if (WindowManagerService.localLOGV) Slog.v(
648 WindowManagerService.TAG, "Got surface: " + mSurface
649 + ", set left=" + mFrame.left + " top=" + mFrame.top
650 + ", animLayer=" + mAnimLayer);
651 if (WindowManagerService.SHOW_TRANSACTIONS) {
652 Slog.i(WindowManagerService.TAG, ">>> OPEN TRANSACTION createSurfaceLocked");
653 WindowManagerService.logSurface(this, "CREATE pos=(" + mFrame.left + "," + mFrame.top + ") (" +
654 mFrame.width() + "x" + mFrame.height() + "), layer=" +
655 mAnimLayer + " HIDE", null);
656 }
657 Surface.openTransaction();
658 try {
659 try {
660 mSurfaceX = mFrame.left + mXOffset;
661 mSurfaceY = mFrame.top + mYOffset;
662 mSurface.setPosition(mSurfaceX, mSurfaceY);
663 mSurfaceLayer = mAnimLayer;
664 mSurface.setLayer(mAnimLayer);
665 mSurfaceShown = false;
666 mSurface.hide();
667 if ((mAttrs.flags&WindowManager.LayoutParams.FLAG_DITHER) != 0) {
668 if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(this, "DITHER", null);
669 mSurface.setFlags(Surface.SURFACE_DITHER,
670 Surface.SURFACE_DITHER);
671 }
672 } catch (RuntimeException e) {
673 Slog.w(WindowManagerService.TAG, "Error creating surface in " + w, e);
Dianne Hackborn64825172011-03-02 21:32:58 -0800674 mService.reclaimSomeSurfaceMemoryLocked(this, "create-init", true);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800675 }
676 mLastHidden = true;
677 } finally {
678 Surface.closeTransaction();
679 if (WindowManagerService.SHOW_TRANSACTIONS) Slog.i(WindowManagerService.TAG, "<<< CLOSE TRANSACTION createSurfaceLocked");
680 }
681 if (WindowManagerService.localLOGV) Slog.v(
682 WindowManagerService.TAG, "Created surface " + this);
683 }
684 return mSurface;
685 }
686
687 void destroySurfaceLocked() {
688 if (mAppToken != null && this == mAppToken.startingWindow) {
689 mAppToken.startingDisplayed = false;
690 }
691
692 if (mSurface != null) {
693 mDrawPending = false;
694 mCommitDrawPending = false;
695 mReadyToShow = false;
696
697 int i = mChildWindows.size();
698 while (i > 0) {
699 i--;
700 WindowState c = mChildWindows.get(i);
701 c.mAttachedHidden = true;
702 }
703
704 if (mReportDestroySurface) {
705 mReportDestroySurface = false;
706 mSurfacePendingDestroy = true;
707 try {
708 mClient.dispatchGetNewSurface();
709 // We'll really destroy on the next time around.
710 return;
711 } catch (RemoteException e) {
712 }
713 }
714
715 try {
716 if (WindowManagerService.DEBUG_VISIBILITY) {
717 RuntimeException e = null;
718 if (!WindowManagerService.HIDE_STACK_CRAWLS) {
719 e = new RuntimeException();
720 e.fillInStackTrace();
721 }
722 Slog.w(WindowManagerService.TAG, "Window " + this + " destroying surface "
723 + mSurface + ", session " + mSession, e);
724 }
725 if (WindowManagerService.SHOW_TRANSACTIONS) {
726 RuntimeException e = null;
727 if (!WindowManagerService.HIDE_STACK_CRAWLS) {
728 e = new RuntimeException();
729 e.fillInStackTrace();
730 }
731 if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(this, "DESTROY", e);
732 }
733 mSurface.destroy();
734 } catch (RuntimeException e) {
735 Slog.w(WindowManagerService.TAG, "Exception thrown when destroying Window " + this
736 + " surface " + mSurface + " session " + mSession
737 + ": " + e.toString());
738 }
739
740 mSurfaceShown = false;
741 mSurface = null;
742 }
743 }
744
745 boolean finishDrawingLocked() {
746 if (mDrawPending) {
747 if (WindowManagerService.SHOW_TRANSACTIONS || WindowManagerService.DEBUG_ORIENTATION) Slog.v(
748 WindowManagerService.TAG, "finishDrawingLocked: " + mSurface);
749 mCommitDrawPending = true;
750 mDrawPending = false;
751 return true;
752 }
753 return false;
754 }
755
756 // This must be called while inside a transaction.
757 boolean commitFinishDrawingLocked(long currentTime) {
758 //Slog.i(TAG, "commitFinishDrawingLocked: " + mSurface);
759 if (!mCommitDrawPending) {
760 return false;
761 }
762 mCommitDrawPending = false;
763 mReadyToShow = true;
764 final boolean starting = mAttrs.type == TYPE_APPLICATION_STARTING;
765 final AppWindowToken atoken = mAppToken;
766 if (atoken == null || atoken.allDrawn || starting) {
767 performShowLocked();
768 }
769 return true;
770 }
771
772 // This must be called while inside a transaction.
773 boolean performShowLocked() {
774 if (WindowManagerService.DEBUG_VISIBILITY) {
775 RuntimeException e = null;
776 if (!WindowManagerService.HIDE_STACK_CRAWLS) {
777 e = new RuntimeException();
778 e.fillInStackTrace();
779 }
780 Slog.v(WindowManagerService.TAG, "performShow on " + this
781 + ": readyToShow=" + mReadyToShow + " readyForDisplay=" + isReadyForDisplay()
782 + " starting=" + (mAttrs.type == TYPE_APPLICATION_STARTING), e);
783 }
784 if (mReadyToShow && isReadyForDisplay()) {
785 if (WindowManagerService.SHOW_TRANSACTIONS || WindowManagerService.DEBUG_ORIENTATION) WindowManagerService.logSurface(this,
786 "SHOW (performShowLocked)", null);
787 if (WindowManagerService.DEBUG_VISIBILITY) Slog.v(WindowManagerService.TAG, "Showing " + this
788 + " during animation: policyVis=" + mPolicyVisibility
789 + " attHidden=" + mAttachedHidden
790 + " tok.hiddenRequested="
791 + (mAppToken != null ? mAppToken.hiddenRequested : false)
792 + " tok.hidden="
793 + (mAppToken != null ? mAppToken.hidden : false)
794 + " animating=" + mAnimating
795 + " tok animating="
796 + (mAppToken != null ? mAppToken.animating : false));
797 if (!mService.showSurfaceRobustlyLocked(this)) {
798 return false;
799 }
800 mLastAlpha = -1;
801 mHasDrawn = true;
802 mLastHidden = false;
803 mReadyToShow = false;
804 mService.enableScreenIfNeededLocked();
805
806 mService.applyEnterAnimationLocked(this);
807
808 int i = mChildWindows.size();
809 while (i > 0) {
810 i--;
811 WindowState c = mChildWindows.get(i);
812 if (c.mAttachedHidden) {
813 c.mAttachedHidden = false;
814 if (c.mSurface != null) {
815 c.performShowLocked();
816 // It hadn't been shown, which means layout not
817 // performed on it, so now we want to make sure to
818 // do a layout. If called from within the transaction
819 // loop, this will cause it to restart with a new
820 // layout.
821 mService.mLayoutNeeded = true;
822 }
823 }
824 }
825
826 if (mAttrs.type != TYPE_APPLICATION_STARTING
827 && mAppToken != null) {
828 mAppToken.firstWindowDrawn = true;
829
830 if (mAppToken.startingData != null) {
831 if (WindowManagerService.DEBUG_STARTING_WINDOW || WindowManagerService.DEBUG_ANIM) Slog.v(WindowManagerService.TAG,
832 "Finish starting " + mToken
833 + ": first real window is shown, no animation");
834 // If this initial window is animating, stop it -- we
835 // will do an animation to reveal it from behind the
836 // starting window, so there is no need for it to also
837 // be doing its own stuff.
838 if (mAnimation != null) {
839 mAnimation.cancel();
840 mAnimation = null;
841 // Make sure we clean up the animation.
842 mAnimating = true;
843 }
844 mService.mFinishedStarting.add(mAppToken);
845 mService.mH.sendEmptyMessage(H.FINISHED_STARTING);
846 }
847 mAppToken.updateReportedVisibilityLocked();
848 }
849 }
850 return true;
851 }
852
853 // This must be called while inside a transaction. Returns true if
854 // there is more animation to run.
855 boolean stepAnimationLocked(long currentTime, int dw, int dh) {
856 if (!mService.mDisplayFrozen && mService.mPolicy.isScreenOn()) {
857 // We will run animations as long as the display isn't frozen.
858
859 if (!mDrawPending && !mCommitDrawPending && mAnimation != null) {
860 mHasTransformation = true;
861 mHasLocalTransformation = true;
862 if (!mLocalAnimating) {
863 if (WindowManagerService.DEBUG_ANIM) Slog.v(
864 WindowManagerService.TAG, "Starting animation in " + this +
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400865 " @ " + currentTime + ": ww=" + mScaledFrame.width() +
866 " wh=" + mScaledFrame.height() +
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800867 " dw=" + dw + " dh=" + dh + " scale=" + mService.mWindowAnimationScale);
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400868 mAnimation.initialize(mScaledFrame.width(), mScaledFrame.height(), dw, dh);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -0800869 mAnimation.setStartTime(currentTime);
870 mLocalAnimating = true;
871 mAnimating = true;
872 }
873 mTransformation.clear();
874 final boolean more = mAnimation.getTransformation(
875 currentTime, mTransformation);
876 if (WindowManagerService.DEBUG_ANIM) Slog.v(
877 WindowManagerService.TAG, "Stepped animation in " + this +
878 ": more=" + more + ", xform=" + mTransformation);
879 if (more) {
880 // we're not done!
881 return true;
882 }
883 if (WindowManagerService.DEBUG_ANIM) Slog.v(
884 WindowManagerService.TAG, "Finished animation in " + this +
885 " @ " + currentTime);
886
887 if (mAnimation != null) {
888 mAnimation.cancel();
889 mAnimation = null;
890 }
891 //WindowManagerService.this.dump();
892 }
893 mHasLocalTransformation = false;
894 if ((!mLocalAnimating || mAnimationIsEntrance) && mAppToken != null
895 && mAppToken.animation != null) {
896 // When our app token is animating, we kind-of pretend like
897 // we are as well. Note the mLocalAnimating mAnimationIsEntrance
898 // part of this check means that we will only do this if
899 // our window is not currently exiting, or it is not
900 // locally animating itself. The idea being that one that
901 // is exiting and doing a local animation should be removed
902 // once that animation is done.
903 mAnimating = true;
904 mHasTransformation = true;
905 mTransformation.clear();
906 return false;
907 } else if (mHasTransformation) {
908 // Little trick to get through the path below to act like
909 // we have finished an animation.
910 mAnimating = true;
911 } else if (isAnimating()) {
912 mAnimating = true;
913 }
914 } else if (mAnimation != null) {
915 // If the display is frozen, and there is a pending animation,
916 // clear it and make sure we run the cleanup code.
917 mAnimating = true;
918 mLocalAnimating = true;
919 mAnimation.cancel();
920 mAnimation = null;
921 }
922
923 if (!mAnimating && !mLocalAnimating) {
924 return false;
925 }
926
927 if (WindowManagerService.DEBUG_ANIM) Slog.v(
928 WindowManagerService.TAG, "Animation done in " + this + ": exiting=" + mExiting
929 + ", reportedVisible="
930 + (mAppToken != null ? mAppToken.reportedVisible : false));
931
932 mAnimating = false;
933 mLocalAnimating = false;
934 if (mAnimation != null) {
935 mAnimation.cancel();
936 mAnimation = null;
937 }
938 mAnimLayer = mLayer;
939 if (mIsImWindow) {
940 mAnimLayer += mService.mInputMethodAnimLayerAdjustment;
941 } else if (mIsWallpaper) {
942 mAnimLayer += mService.mWallpaperAnimLayerAdjustment;
943 }
944 if (WindowManagerService.DEBUG_LAYERS) Slog.v(WindowManagerService.TAG, "Stepping win " + this
945 + " anim layer: " + mAnimLayer);
946 mHasTransformation = false;
947 mHasLocalTransformation = false;
948 if (mPolicyVisibility != mPolicyVisibilityAfterAnim) {
949 if (WindowManagerService.DEBUG_VISIBILITY) {
950 Slog.v(WindowManagerService.TAG, "Policy visibility changing after anim in " + this + ": "
951 + mPolicyVisibilityAfterAnim);
952 }
953 mPolicyVisibility = mPolicyVisibilityAfterAnim;
954 if (!mPolicyVisibility) {
955 if (mService.mCurrentFocus == this) {
956 mService.mFocusMayChange = true;
957 }
958 // Window is no longer visible -- make sure if we were waiting
959 // for it to be displayed before enabling the display, that
960 // we allow the display to be enabled now.
961 mService.enableScreenIfNeededLocked();
962 }
963 }
964 mTransformation.clear();
965 if (mHasDrawn
966 && mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING
967 && mAppToken != null
968 && mAppToken.firstWindowDrawn
969 && mAppToken.startingData != null) {
970 if (WindowManagerService.DEBUG_STARTING_WINDOW) Slog.v(WindowManagerService.TAG, "Finish starting "
971 + mToken + ": first real window done animating");
972 mService.mFinishedStarting.add(mAppToken);
973 mService.mH.sendEmptyMessage(H.FINISHED_STARTING);
974 }
975
976 finishExit();
977
978 if (mAppToken != null) {
979 mAppToken.updateReportedVisibilityLocked();
980 }
981
982 return false;
983 }
984
985 void finishExit() {
986 if (WindowManagerService.DEBUG_ANIM) Slog.v(
987 WindowManagerService.TAG, "finishExit in " + this
988 + ": exiting=" + mExiting
989 + " remove=" + mRemoveOnExit
990 + " windowAnimating=" + isWindowAnimating());
991
992 final int N = mChildWindows.size();
993 for (int i=0; i<N; i++) {
994 mChildWindows.get(i).finishExit();
995 }
996
997 if (!mExiting) {
998 return;
999 }
1000
1001 if (isWindowAnimating()) {
1002 return;
1003 }
1004
1005 if (WindowManagerService.localLOGV) Slog.v(
1006 WindowManagerService.TAG, "Exit animation finished in " + this
1007 + ": remove=" + mRemoveOnExit);
1008 if (mSurface != null) {
1009 mService.mDestroySurface.add(this);
1010 mDestroying = true;
1011 if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(this, "HIDE (finishExit)", null);
1012 mSurfaceShown = false;
1013 try {
1014 mSurface.hide();
1015 } catch (RuntimeException e) {
1016 Slog.w(WindowManagerService.TAG, "Error hiding surface in " + this, e);
1017 }
1018 mLastHidden = true;
1019 }
1020 mExiting = false;
1021 if (mRemoveOnExit) {
1022 mService.mPendingRemove.add(this);
1023 mRemoveOnExit = false;
1024 }
1025 }
1026
1027 boolean isIdentityMatrix(float dsdx, float dtdx, float dsdy, float dtdy) {
1028 if (dsdx < .99999f || dsdx > 1.00001f) return false;
1029 if (dtdy < .99999f || dtdy > 1.00001f) return false;
1030 if (dtdx < -.000001f || dtdx > .000001f) return false;
1031 if (dsdy < -.000001f || dsdy > .000001f) return false;
1032 return true;
1033 }
1034
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001035 void prelayout() {
1036 if (mEnforceSizeCompat) {
1037 mGlobalScale = mService.mCompatibleScreenScale;
1038 } else {
1039 mGlobalScale = 1;
1040 }
1041 }
1042
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001043 void computeShownFrameLocked() {
1044 final boolean selfTransformation = mHasLocalTransformation;
1045 Transformation attachedTransformation =
1046 (mAttachedWindow != null && mAttachedWindow.mHasLocalTransformation)
1047 ? mAttachedWindow.mTransformation : null;
1048 Transformation appTransformation =
1049 (mAppToken != null && mAppToken.hasTransformation)
1050 ? mAppToken.transformation : null;
1051
1052 // Wallpapers are animated based on the "real" window they
1053 // are currently targeting.
1054 if (mAttrs.type == TYPE_WALLPAPER && mService.mLowerWallpaperTarget == null
1055 && mService.mWallpaperTarget != null) {
1056 if (mService.mWallpaperTarget.mHasLocalTransformation &&
1057 mService.mWallpaperTarget.mAnimation != null &&
1058 !mService.mWallpaperTarget.mAnimation.getDetachWallpaper()) {
1059 attachedTransformation = mService.mWallpaperTarget.mTransformation;
1060 if (WindowManagerService.DEBUG_WALLPAPER && attachedTransformation != null) {
1061 Slog.v(WindowManagerService.TAG, "WP target attached xform: " + attachedTransformation);
1062 }
1063 }
1064 if (mService.mWallpaperTarget.mAppToken != null &&
1065 mService.mWallpaperTarget.mAppToken.hasTransformation &&
1066 mService.mWallpaperTarget.mAppToken.animation != null &&
1067 !mService.mWallpaperTarget.mAppToken.animation.getDetachWallpaper()) {
1068 appTransformation = mService.mWallpaperTarget.mAppToken.transformation;
1069 if (WindowManagerService.DEBUG_WALLPAPER && appTransformation != null) {
1070 Slog.v(WindowManagerService.TAG, "WP target app xform: " + appTransformation);
1071 }
1072 }
1073 }
1074
1075 final boolean screenAnimation = mService.mScreenRotationAnimation != null
1076 && mService.mScreenRotationAnimation.isAnimating();
1077 if (selfTransformation || attachedTransformation != null
1078 || appTransformation != null || screenAnimation) {
1079 // cache often used attributes locally
1080 final Rect frame = mFrame;
1081 final float tmpFloats[] = mService.mTmpFloats;
1082 final Matrix tmpMatrix = mTmpMatrix;
1083
1084 // Compute the desired transformation.
1085 tmpMatrix.setTranslate(0, 0);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001086 tmpMatrix.postScale(mGlobalScale, mGlobalScale);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001087 if (selfTransformation) {
1088 tmpMatrix.postConcat(mTransformation.getMatrix());
1089 }
1090 tmpMatrix.postTranslate(frame.left + mXOffset, frame.top + mYOffset);
1091 if (attachedTransformation != null) {
1092 tmpMatrix.postConcat(attachedTransformation.getMatrix());
1093 }
1094 if (appTransformation != null) {
1095 tmpMatrix.postConcat(appTransformation.getMatrix());
1096 }
1097 if (screenAnimation) {
1098 tmpMatrix.postConcat(
1099 mService.mScreenRotationAnimation.getEnterTransformation().getMatrix());
1100 }
1101
1102 // "convert" it into SurfaceFlinger's format
1103 // (a 2x2 matrix + an offset)
1104 // Here we must not transform the position of the surface
1105 // since it is already included in the transformation.
1106 //Slog.i(TAG, "Transform: " + matrix);
1107
1108 mHaveMatrix = true;
1109 tmpMatrix.getValues(tmpFloats);
1110 mDsDx = tmpFloats[Matrix.MSCALE_X];
1111 mDtDx = tmpFloats[Matrix.MSKEW_Y];
1112 mDsDy = tmpFloats[Matrix.MSKEW_X];
1113 mDtDy = tmpFloats[Matrix.MSCALE_Y];
1114 int x = (int)tmpFloats[Matrix.MTRANS_X];
1115 int y = (int)tmpFloats[Matrix.MTRANS_Y];
1116 int w = frame.width();
1117 int h = frame.height();
1118 mShownFrame.set(x, y, x+w, y+h);
1119
1120 // Now set the alpha... but because our current hardware
1121 // can't do alpha transformation on a non-opaque surface,
1122 // turn it off if we are running an animation that is also
1123 // transforming since it is more important to have that
1124 // animation be smooth.
1125 mShownAlpha = mAlpha;
1126 if (!mService.mLimitedAlphaCompositing
1127 || (!PixelFormat.formatHasAlpha(mAttrs.format)
1128 || (isIdentityMatrix(mDsDx, mDtDx, mDsDy, mDtDy)
1129 && x == frame.left && y == frame.top))) {
1130 //Slog.i(TAG, "Applying alpha transform");
1131 if (selfTransformation) {
1132 mShownAlpha *= mTransformation.getAlpha();
1133 }
1134 if (attachedTransformation != null) {
1135 mShownAlpha *= attachedTransformation.getAlpha();
1136 }
1137 if (appTransformation != null) {
1138 mShownAlpha *= appTransformation.getAlpha();
1139 }
1140 if (screenAnimation) {
1141 mShownAlpha *=
1142 mService.mScreenRotationAnimation.getEnterTransformation().getAlpha();
1143 }
1144 } else {
1145 //Slog.i(TAG, "Not applying alpha transform");
1146 }
1147
1148 if (WindowManagerService.localLOGV) Slog.v(
1149 WindowManagerService.TAG, "Continuing animation in " + this +
1150 ": " + mShownFrame +
1151 ", alpha=" + mTransformation.getAlpha());
1152 return;
1153 }
1154
1155 mShownFrame.set(mFrame);
1156 if (mXOffset != 0 || mYOffset != 0) {
1157 mShownFrame.offset(mXOffset, mYOffset);
1158 }
1159 mShownAlpha = mAlpha;
1160 mHaveMatrix = false;
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001161 mDsDx = mGlobalScale;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001162 mDtDx = 0;
1163 mDsDy = 0;
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001164 mDtDy = mGlobalScale;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001165 }
1166
1167 /**
1168 * Is this window visible? It is not visible if there is no
1169 * surface, or we are in the process of running an exit animation
1170 * that will remove the surface, or its app token has been hidden.
1171 */
1172 public boolean isVisibleLw() {
1173 final AppWindowToken atoken = mAppToken;
1174 return mSurface != null && mPolicyVisibility && !mAttachedHidden
1175 && (atoken == null || !atoken.hiddenRequested)
1176 && !mExiting && !mDestroying;
1177 }
1178
1179 /**
1180 * Like {@link #isVisibleLw}, but also counts a window that is currently
1181 * "hidden" behind the keyguard as visible. This allows us to apply
1182 * things like window flags that impact the keyguard.
1183 * XXX I am starting to think we need to have ANOTHER visibility flag
1184 * for this "hidden behind keyguard" state rather than overloading
1185 * mPolicyVisibility. Ungh.
1186 */
1187 public boolean isVisibleOrBehindKeyguardLw() {
1188 final AppWindowToken atoken = mAppToken;
1189 return mSurface != null && !mAttachedHidden
1190 && (atoken == null ? mPolicyVisibility : !atoken.hiddenRequested)
1191 && !mDrawPending && !mCommitDrawPending
1192 && !mExiting && !mDestroying;
1193 }
1194
1195 /**
1196 * Is this window visible, ignoring its app token? It is not visible
1197 * if there is no surface, or we are in the process of running an exit animation
1198 * that will remove the surface.
1199 */
1200 public boolean isWinVisibleLw() {
1201 final AppWindowToken atoken = mAppToken;
1202 return mSurface != null && mPolicyVisibility && !mAttachedHidden
1203 && (atoken == null || !atoken.hiddenRequested || atoken.animating)
1204 && !mExiting && !mDestroying;
1205 }
1206
1207 /**
1208 * The same as isVisible(), but follows the current hidden state of
1209 * the associated app token, not the pending requested hidden state.
1210 */
1211 boolean isVisibleNow() {
1212 return mSurface != null && mPolicyVisibility && !mAttachedHidden
1213 && !mRootToken.hidden && !mExiting && !mDestroying;
1214 }
1215
1216 /**
1217 * Can this window possibly be a drag/drop target? The test here is
1218 * a combination of the above "visible now" with the check that the
1219 * Input Manager uses when discarding windows from input consideration.
1220 */
1221 boolean isPotentialDragTarget() {
1222 return isVisibleNow() && (mInputChannel != null) && !mRemoved;
1223 }
1224
1225 /**
1226 * Same as isVisible(), but we also count it as visible between the
1227 * call to IWindowSession.add() and the first relayout().
1228 */
1229 boolean isVisibleOrAdding() {
1230 final AppWindowToken atoken = mAppToken;
1231 return ((mSurface != null && !mReportDestroySurface)
1232 || (!mRelayoutCalled && mViewVisibility == View.VISIBLE))
1233 && mPolicyVisibility && !mAttachedHidden
1234 && (atoken == null || !atoken.hiddenRequested)
1235 && !mExiting && !mDestroying;
1236 }
1237
1238 /**
1239 * Is this window currently on-screen? It is on-screen either if it
1240 * is visible or it is currently running an animation before no longer
1241 * being visible.
1242 */
1243 boolean isOnScreen() {
1244 final AppWindowToken atoken = mAppToken;
1245 if (atoken != null) {
1246 return mSurface != null && mPolicyVisibility && !mDestroying
1247 && ((!mAttachedHidden && !atoken.hiddenRequested)
1248 || mAnimation != null || atoken.animation != null);
1249 } else {
1250 return mSurface != null && mPolicyVisibility && !mDestroying
1251 && (!mAttachedHidden || mAnimation != null);
1252 }
1253 }
1254
1255 /**
1256 * Like isOnScreen(), but we don't return true if the window is part
1257 * of a transition that has not yet been started.
1258 */
1259 boolean isReadyForDisplay() {
1260 if (mRootToken.waitingToShow &&
1261 mService.mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
1262 return false;
1263 }
1264 final AppWindowToken atoken = mAppToken;
1265 final boolean animating = atoken != null
1266 ? (atoken.animation != null) : false;
1267 return mSurface != null && mPolicyVisibility && !mDestroying
1268 && ((!mAttachedHidden && mViewVisibility == View.VISIBLE
1269 && !mRootToken.hidden)
1270 || mAnimation != null || animating);
1271 }
1272
1273 /** Is the window or its container currently animating? */
1274 boolean isAnimating() {
1275 final WindowState attached = mAttachedWindow;
1276 final AppWindowToken atoken = mAppToken;
1277 return mAnimation != null
1278 || (attached != null && attached.mAnimation != null)
1279 || (atoken != null &&
1280 (atoken.animation != null
1281 || atoken.inPendingTransaction));
1282 }
1283
1284 /** Is this window currently animating? */
1285 boolean isWindowAnimating() {
1286 return mAnimation != null;
1287 }
1288
1289 /**
1290 * Like isOnScreen, but returns false if the surface hasn't yet
1291 * been drawn.
1292 */
1293 public boolean isDisplayedLw() {
1294 final AppWindowToken atoken = mAppToken;
1295 return mSurface != null && mPolicyVisibility && !mDestroying
1296 && !mDrawPending && !mCommitDrawPending
1297 && ((!mAttachedHidden &&
1298 (atoken == null || !atoken.hiddenRequested))
1299 || mAnimating);
1300 }
1301
1302 /**
1303 * Returns true if the window has a surface that it has drawn a
1304 * complete UI in to.
1305 */
1306 public boolean isDrawnLw() {
1307 final AppWindowToken atoken = mAppToken;
1308 return mSurface != null && !mDestroying
1309 && !mDrawPending && !mCommitDrawPending;
1310 }
1311
1312 /**
1313 * Return true if the window is opaque and fully drawn. This indicates
1314 * it may obscure windows behind it.
1315 */
1316 boolean isOpaqueDrawn() {
1317 return (mAttrs.format == PixelFormat.OPAQUE
1318 || mAttrs.type == TYPE_WALLPAPER)
1319 && mSurface != null && mAnimation == null
1320 && (mAppToken == null || mAppToken.animation == null)
1321 && !mDrawPending && !mCommitDrawPending;
1322 }
1323
1324 /**
1325 * Return whether this window is wanting to have a translation
1326 * animation applied to it for an in-progress move. (Only makes
1327 * sense to call from performLayoutAndPlaceSurfacesLockedInner().)
1328 */
1329 boolean shouldAnimateMove() {
1330 return mContentChanged && !mExiting && !mLastHidden && !mService.mDisplayFrozen
1331 && (mFrame.top != mLastFrame.top
1332 || mFrame.left != mLastFrame.left)
1333 && (mAttachedWindow == null || !mAttachedWindow.shouldAnimateMove())
1334 && mService.mPolicy.isScreenOn();
1335 }
1336
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001337 void evalNeedsBackgroundFiller(int screenWidth, int screenHeight) {
1338 mNeedsBackgroundFiller =
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001339 // only if the application is requesting compatible window
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001340 mEnforceSizeCompat &&
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001341 // only if it's visible
1342 mHasDrawn && mViewVisibility == View.VISIBLE &&
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001343 // not needed if the compat window is actually full screen
1344 !isFullscreenIgnoringCompat(screenWidth, screenHeight) &&
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001345 // and only if the application fills the compatible screen
1346 mFrame.left <= mService.mCompatibleScreenFrame.left &&
1347 mFrame.top <= mService.mCompatibleScreenFrame.top &&
1348 mFrame.right >= mService.mCompatibleScreenFrame.right &&
1349 mFrame.bottom >= mService.mCompatibleScreenFrame.bottom;
1350 }
1351
1352 boolean isFullscreen(int screenWidth, int screenHeight) {
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001353 if (mEnforceSizeCompat) {
1354 return mFrame.left <= mService.mCompatibleScreenFrame.left &&
1355 mFrame.top <= mService.mCompatibleScreenFrame.top &&
1356 mFrame.right >= mService.mCompatibleScreenFrame.right &&
1357 mFrame.bottom >= mService.mCompatibleScreenFrame.bottom;
1358 } else {
1359 return isFullscreenIgnoringCompat(screenWidth, screenHeight);
1360 }
1361 }
1362
1363 boolean isFullscreenIgnoringCompat(int screenWidth, int screenHeight) {
1364 return mScaledFrame.left <= 0 && mScaledFrame.top <= 0 &&
1365 mScaledFrame.right >= screenWidth && mScaledFrame.bottom >= screenHeight;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001366 }
1367
1368 void removeLocked() {
1369 disposeInputChannel();
1370
1371 if (mAttachedWindow != null) {
1372 if (WindowManagerService.DEBUG_ADD_REMOVE) Slog.v(WindowManagerService.TAG, "Removing " + this + " from " + mAttachedWindow);
1373 mAttachedWindow.mChildWindows.remove(this);
1374 }
1375 destroySurfaceLocked();
1376 mSession.windowRemovedLocked();
1377 try {
1378 mClient.asBinder().unlinkToDeath(mDeathRecipient, 0);
1379 } catch (RuntimeException e) {
1380 // Ignore if it has already been removed (usually because
1381 // we are doing this as part of processing a death note.)
1382 }
1383 }
1384
1385 void disposeInputChannel() {
1386 if (mInputChannel != null) {
1387 mService.mInputManager.unregisterInputChannel(mInputChannel);
1388
1389 mInputChannel.dispose();
1390 mInputChannel = null;
1391 }
1392 }
1393
1394 private class DeathRecipient implements IBinder.DeathRecipient {
1395 public void binderDied() {
1396 try {
1397 synchronized(mService.mWindowMap) {
1398 WindowState win = mService.windowForClientLocked(mSession, mClient, false);
1399 Slog.i(WindowManagerService.TAG, "WIN DEATH: " + win);
1400 if (win != null) {
1401 mService.removeWindowLocked(mSession, win);
1402 }
1403 }
1404 } catch (IllegalArgumentException ex) {
1405 // This will happen if the window has already been
1406 // removed.
1407 }
1408 }
1409 }
1410
1411 /** Returns true if this window desires key events. */
1412 public final boolean canReceiveKeys() {
1413 return isVisibleOrAdding()
1414 && (mViewVisibility == View.VISIBLE)
1415 && ((mAttrs.flags & WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE) == 0);
1416 }
1417
1418 public boolean hasDrawnLw() {
1419 return mHasDrawn;
1420 }
1421
1422 public boolean showLw(boolean doAnimation) {
1423 return showLw(doAnimation, true);
1424 }
1425
1426 boolean showLw(boolean doAnimation, boolean requestAnim) {
1427 if (mPolicyVisibility && mPolicyVisibilityAfterAnim) {
1428 return false;
1429 }
1430 if (WindowManagerService.DEBUG_VISIBILITY) Slog.v(WindowManagerService.TAG, "Policy visibility true: " + this);
1431 if (doAnimation) {
1432 if (WindowManagerService.DEBUG_VISIBILITY) Slog.v(WindowManagerService.TAG, "doAnimation: mPolicyVisibility="
1433 + mPolicyVisibility + " mAnimation=" + mAnimation);
1434 if (mService.mDisplayFrozen || !mService.mPolicy.isScreenOn()) {
1435 doAnimation = false;
1436 } else if (mPolicyVisibility && mAnimation == null) {
1437 // Check for the case where we are currently visible and
1438 // not animating; we do not want to do animation at such a
1439 // point to become visible when we already are.
1440 doAnimation = false;
1441 }
1442 }
1443 mPolicyVisibility = true;
1444 mPolicyVisibilityAfterAnim = true;
1445 if (doAnimation) {
1446 mService.applyAnimationLocked(this, WindowManagerPolicy.TRANSIT_ENTER, true);
1447 }
1448 if (requestAnim) {
1449 mService.requestAnimationLocked(0);
1450 }
1451 return true;
1452 }
1453
1454 public boolean hideLw(boolean doAnimation) {
1455 return hideLw(doAnimation, true);
1456 }
1457
1458 boolean hideLw(boolean doAnimation, boolean requestAnim) {
1459 if (doAnimation) {
1460 if (mService.mDisplayFrozen || !mService.mPolicy.isScreenOn()) {
1461 doAnimation = false;
1462 }
1463 }
1464 boolean current = doAnimation ? mPolicyVisibilityAfterAnim
1465 : mPolicyVisibility;
1466 if (!current) {
1467 return false;
1468 }
1469 if (doAnimation) {
1470 mService.applyAnimationLocked(this, WindowManagerPolicy.TRANSIT_EXIT, false);
1471 if (mAnimation == null) {
1472 doAnimation = false;
1473 }
1474 }
1475 if (doAnimation) {
1476 mPolicyVisibilityAfterAnim = false;
1477 } else {
1478 if (WindowManagerService.DEBUG_VISIBILITY) Slog.v(WindowManagerService.TAG, "Policy visibility false: " + this);
1479 mPolicyVisibilityAfterAnim = false;
1480 mPolicyVisibility = false;
1481 // Window is no longer visible -- make sure if we were waiting
1482 // for it to be displayed before enabling the display, that
1483 // we allow the display to be enabled now.
1484 mService.enableScreenIfNeededLocked();
1485 if (mService.mCurrentFocus == this) {
1486 mService.mFocusMayChange = true;
1487 }
1488 }
1489 if (requestAnim) {
1490 mService.requestAnimationLocked(0);
1491 }
1492 return true;
1493 }
1494
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001495 private static void applyScaledInsets(Region outRegion, Rect frame, Rect inset, float scale) {
1496 if (scale != 1) {
1497 outRegion.set(frame.left + (int)(inset.left*scale),
1498 frame.top + (int)(inset.top*scale),
1499 frame.right - (int)(inset.right*scale),
1500 frame.bottom - (int)(inset.bottom*scale));
1501 } else {
1502 outRegion.set(
1503 frame.left + inset.left, frame.top + inset.top,
1504 frame.right - inset.right, frame.bottom - inset.bottom);
1505 }
1506 }
1507
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001508 public void getTouchableRegion(Region outRegion) {
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001509 final Rect frame = mScaledFrame;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001510 switch (mTouchableInsets) {
1511 default:
1512 case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME:
1513 outRegion.set(frame);
1514 break;
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001515 case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_CONTENT:
1516 applyScaledInsets(outRegion, frame, mGivenContentInsets, mGlobalScale);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001517 break;
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001518 case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_VISIBLE:
1519 applyScaledInsets(outRegion, frame, mGivenVisibleInsets, mGlobalScale);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001520 break;
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001521 case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION: {
1522 final Region givenTouchableRegion = mGivenTouchableRegion;
1523 outRegion.set(givenTouchableRegion);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001524 if (mGlobalScale != 1) {
1525 outRegion.scale(mGlobalScale);
1526 }
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001527 outRegion.translate(frame.left, frame.top);
1528 break;
1529 }
1530 }
1531 }
1532
1533 void dump(PrintWriter pw, String prefix) {
1534 pw.print(prefix); pw.print("mSession="); pw.print(mSession);
1535 pw.print(" mClient="); pw.println(mClient.asBinder());
1536 pw.print(prefix); pw.print("mAttrs="); pw.println(mAttrs);
1537 if (mAttachedWindow != null || mLayoutAttached) {
1538 pw.print(prefix); pw.print("mAttachedWindow="); pw.print(mAttachedWindow);
1539 pw.print(" mLayoutAttached="); pw.println(mLayoutAttached);
1540 }
1541 if (mIsImWindow || mIsWallpaper || mIsFloatingLayer) {
1542 pw.print(prefix); pw.print("mIsImWindow="); pw.print(mIsImWindow);
1543 pw.print(" mIsWallpaper="); pw.print(mIsWallpaper);
1544 pw.print(" mIsFloatingLayer="); pw.print(mIsFloatingLayer);
1545 pw.print(" mWallpaperVisible="); pw.println(mWallpaperVisible);
1546 }
1547 pw.print(prefix); pw.print("mBaseLayer="); pw.print(mBaseLayer);
1548 pw.print(" mSubLayer="); pw.print(mSubLayer);
1549 pw.print(" mAnimLayer="); pw.print(mLayer); pw.print("+");
1550 pw.print((mTargetAppToken != null ? mTargetAppToken.animLayerAdjustment
1551 : (mAppToken != null ? mAppToken.animLayerAdjustment : 0)));
1552 pw.print("="); pw.print(mAnimLayer);
1553 pw.print(" mLastLayer="); pw.println(mLastLayer);
1554 if (mSurface != null) {
1555 pw.print(prefix); pw.print("mSurface="); pw.println(mSurface);
1556 pw.print(prefix); pw.print("Surface: shown="); pw.print(mSurfaceShown);
1557 pw.print(" layer="); pw.print(mSurfaceLayer);
1558 pw.print(" alpha="); pw.print(mSurfaceAlpha);
1559 pw.print(" rect=("); pw.print(mSurfaceX);
1560 pw.print(","); pw.print(mSurfaceY);
1561 pw.print(") "); pw.print(mSurfaceW);
1562 pw.print(" x "); pw.println(mSurfaceH);
1563 }
1564 pw.print(prefix); pw.print("mToken="); pw.println(mToken);
1565 pw.print(prefix); pw.print("mRootToken="); pw.println(mRootToken);
1566 if (mAppToken != null) {
1567 pw.print(prefix); pw.print("mAppToken="); pw.println(mAppToken);
1568 }
1569 if (mTargetAppToken != null) {
1570 pw.print(prefix); pw.print("mTargetAppToken="); pw.println(mTargetAppToken);
1571 }
1572 pw.print(prefix); pw.print("mViewVisibility=0x");
1573 pw.print(Integer.toHexString(mViewVisibility));
1574 pw.print(" mLastHidden="); pw.print(mLastHidden);
1575 pw.print(" mHaveFrame="); pw.print(mHaveFrame);
1576 pw.print(" mObscured="); pw.println(mObscured);
1577 if (!mPolicyVisibility || !mPolicyVisibilityAfterAnim || mAttachedHidden) {
1578 pw.print(prefix); pw.print("mPolicyVisibility=");
1579 pw.print(mPolicyVisibility);
1580 pw.print(" mPolicyVisibilityAfterAnim=");
1581 pw.print(mPolicyVisibilityAfterAnim);
1582 pw.print(" mAttachedHidden="); pw.println(mAttachedHidden);
1583 }
1584 if (!mRelayoutCalled) {
1585 pw.print(prefix); pw.print("mRelayoutCalled="); pw.println(mRelayoutCalled);
1586 }
1587 pw.print(prefix); pw.print("Requested w="); pw.print(mRequestedWidth);
1588 pw.print(" h="); pw.print(mRequestedHeight);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001589 pw.print(" mLayoutSeq="); pw.print(mLayoutSeq);
1590 pw.print(" mNeedsBackgroundFiller="); pw.println(mNeedsBackgroundFiller);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001591 if (mXOffset != 0 || mYOffset != 0) {
1592 pw.print(prefix); pw.print("Offsets x="); pw.print(mXOffset);
1593 pw.print(" y="); pw.println(mYOffset);
1594 }
1595 pw.print(prefix); pw.print("mGivenContentInsets=");
1596 mGivenContentInsets.printShortString(pw);
1597 pw.print(" mGivenVisibleInsets=");
1598 mGivenVisibleInsets.printShortString(pw);
1599 pw.println();
1600 if (mTouchableInsets != 0 || mGivenInsetsPending) {
1601 pw.print(prefix); pw.print("mTouchableInsets="); pw.print(mTouchableInsets);
1602 pw.print(" mGivenInsetsPending="); pw.println(mGivenInsetsPending);
1603 }
1604 pw.print(prefix); pw.print("mConfiguration="); pw.println(mConfiguration);
1605 pw.print(prefix); pw.print("mShownFrame=");
1606 mShownFrame.printShortString(pw);
1607 pw.print(" last="); mLastShownFrame.printShortString(pw);
1608 pw.println();
1609 pw.print(prefix); pw.print("mFrame="); mFrame.printShortString(pw);
1610 pw.print(" last="); mLastFrame.printShortString(pw);
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001611 pw.print(" scaled="); mScaledFrame.printShortString(pw);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001612 pw.println();
1613 pw.print(prefix); pw.print("mContainingFrame=");
1614 mContainingFrame.printShortString(pw);
1615 pw.print(" mParentFrame=");
1616 mParentFrame.printShortString(pw);
1617 pw.print(" mDisplayFrame=");
1618 mDisplayFrame.printShortString(pw);
1619 pw.println();
1620 pw.print(prefix); pw.print("mContentFrame="); mContentFrame.printShortString(pw);
1621 pw.print(" mVisibleFrame="); mVisibleFrame.printShortString(pw);
1622 pw.println();
1623 pw.print(prefix); pw.print("mContentInsets="); mContentInsets.printShortString(pw);
1624 pw.print(" last="); mLastContentInsets.printShortString(pw);
1625 pw.print(" mVisibleInsets="); mVisibleInsets.printShortString(pw);
1626 pw.print(" last="); mLastVisibleInsets.printShortString(pw);
1627 pw.println();
1628 if (mAnimating || mLocalAnimating || mAnimationIsEntrance
1629 || mAnimation != null) {
1630 pw.print(prefix); pw.print("mAnimating="); pw.print(mAnimating);
1631 pw.print(" mLocalAnimating="); pw.print(mLocalAnimating);
1632 pw.print(" mAnimationIsEntrance="); pw.print(mAnimationIsEntrance);
1633 pw.print(" mAnimation="); pw.println(mAnimation);
1634 }
1635 if (mHasTransformation || mHasLocalTransformation) {
1636 pw.print(prefix); pw.print("XForm: has=");
1637 pw.print(mHasTransformation);
1638 pw.print(" hasLocal="); pw.print(mHasLocalTransformation);
1639 pw.print(" "); mTransformation.printShortString(pw);
1640 pw.println();
1641 }
1642 if (mShownAlpha != 1 || mAlpha != 1 || mLastAlpha != 1) {
1643 pw.print(prefix); pw.print("mShownAlpha="); pw.print(mShownAlpha);
1644 pw.print(" mAlpha="); pw.print(mAlpha);
1645 pw.print(" mLastAlpha="); pw.println(mLastAlpha);
1646 }
Dianne Hackborne2515ee2011-04-27 18:52:56 -04001647 if (mHaveMatrix || mGlobalScale != 1) {
1648 pw.print(prefix); pw.print("mGlobalScale="); pw.print(mGlobalScale);
1649 pw.print(" mDsDx="); pw.print(mDsDx);
Dianne Hackborn6e1eb762011-02-17 16:07:28 -08001650 pw.print(" mDtDx="); pw.print(mDtDx);
1651 pw.print(" mDsDy="); pw.print(mDsDy);
1652 pw.print(" mDtDy="); pw.println(mDtDy);
1653 }
1654 pw.print(prefix); pw.print("mDrawPending="); pw.print(mDrawPending);
1655 pw.print(" mCommitDrawPending="); pw.print(mCommitDrawPending);
1656 pw.print(" mReadyToShow="); pw.print(mReadyToShow);
1657 pw.print(" mHasDrawn="); pw.println(mHasDrawn);
1658 if (mExiting || mRemoveOnExit || mDestroying || mRemoved) {
1659 pw.print(prefix); pw.print("mExiting="); pw.print(mExiting);
1660 pw.print(" mRemoveOnExit="); pw.print(mRemoveOnExit);
1661 pw.print(" mDestroying="); pw.print(mDestroying);
1662 pw.print(" mRemoved="); pw.println(mRemoved);
1663 }
1664 if (mOrientationChanging || mAppFreezing || mTurnOnScreen) {
1665 pw.print(prefix); pw.print("mOrientationChanging=");
1666 pw.print(mOrientationChanging);
1667 pw.print(" mAppFreezing="); pw.print(mAppFreezing);
1668 pw.print(" mTurnOnScreen="); pw.println(mTurnOnScreen);
1669 }
1670 if (mHScale != 1 || mVScale != 1) {
1671 pw.print(prefix); pw.print("mHScale="); pw.print(mHScale);
1672 pw.print(" mVScale="); pw.println(mVScale);
1673 }
1674 if (mWallpaperX != -1 || mWallpaperY != -1) {
1675 pw.print(prefix); pw.print("mWallpaperX="); pw.print(mWallpaperX);
1676 pw.print(" mWallpaperY="); pw.println(mWallpaperY);
1677 }
1678 if (mWallpaperXStep != -1 || mWallpaperYStep != -1) {
1679 pw.print(prefix); pw.print("mWallpaperXStep="); pw.print(mWallpaperXStep);
1680 pw.print(" mWallpaperYStep="); pw.println(mWallpaperYStep);
1681 }
1682 }
1683
1684 String makeInputChannelName() {
1685 return Integer.toHexString(System.identityHashCode(this))
1686 + " " + mAttrs.getTitle();
1687 }
1688
1689 @Override
1690 public String toString() {
1691 if (mStringNameCache == null || mLastTitle != mAttrs.getTitle()
1692 || mWasPaused != mToken.paused) {
1693 mLastTitle = mAttrs.getTitle();
1694 mWasPaused = mToken.paused;
1695 mStringNameCache = "Window{" + Integer.toHexString(System.identityHashCode(this))
1696 + " " + mLastTitle + " paused=" + mWasPaused + "}";
1697 }
1698 return mStringNameCache;
1699 }
1700}