• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
17 package com.android.server.wm;
18 
19 import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW;
20 import static android.view.WindowManager.LayoutParams.FLAG_COMPATIBLE_WINDOW;
21 import static android.view.WindowManager.LayoutParams.LAST_SUB_WINDOW;
22 import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
23 import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD_DIALOG;
24 import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
25 
26 import com.android.server.input.InputWindowHandle;
27 
28 import android.content.Context;
29 import android.content.res.Configuration;
30 import android.graphics.Matrix;
31 import android.graphics.PixelFormat;
32 import android.graphics.Rect;
33 import android.graphics.RectF;
34 import android.graphics.Region;
35 import android.os.IBinder;
36 import android.os.RemoteException;
37 import android.util.Slog;
38 import android.view.Gravity;
39 import android.view.IApplicationToken;
40 import android.view.IWindow;
41 import android.view.InputChannel;
42 import android.view.View;
43 import android.view.ViewTreeObserver;
44 import android.view.WindowManager;
45 import android.view.WindowManagerPolicy;
46 
47 import java.io.PrintWriter;
48 import java.util.ArrayList;
49 
50 /**
51  * A window in the window manager.
52  */
53 final class WindowState implements WindowManagerPolicy.WindowState {
54     static final String TAG = "WindowState";
55 
56     static final boolean DEBUG_VISIBILITY = WindowManagerService.DEBUG_VISIBILITY;
57     static final boolean SHOW_TRANSACTIONS = WindowManagerService.SHOW_TRANSACTIONS;
58     static final boolean SHOW_LIGHT_TRANSACTIONS = WindowManagerService.SHOW_LIGHT_TRANSACTIONS;
59     static final boolean SHOW_SURFACE_ALLOC = WindowManagerService.SHOW_SURFACE_ALLOC;
60 
61     final WindowManagerService mService;
62     final WindowManagerPolicy mPolicy;
63     final Context mContext;
64     final Session mSession;
65     final IWindow mClient;
66     WindowToken mToken;
67     WindowToken mRootToken;
68     AppWindowToken mAppToken;
69     AppWindowToken mTargetAppToken;
70 
71     // mAttrs.flags is tested in animation without being locked. If the bits tested are ever
72     // modified they will need to be locked.
73     final WindowManager.LayoutParams mAttrs = new WindowManager.LayoutParams();
74     final DeathRecipient mDeathRecipient;
75     final WindowState mAttachedWindow;
76     final ArrayList<WindowState> mChildWindows = new ArrayList<WindowState>();
77     final int mBaseLayer;
78     final int mSubLayer;
79     final boolean mLayoutAttached;
80     final boolean mIsImWindow;
81     final boolean mIsWallpaper;
82     final boolean mIsFloatingLayer;
83     int mSeq;
84     boolean mEnforceSizeCompat;
85     int mViewVisibility;
86     int mSystemUiVisibility;
87     boolean mPolicyVisibility = true;
88     boolean mPolicyVisibilityAfterAnim = true;
89     boolean mAppFreezing;
90     boolean mAttachedHidden;    // is our parent window hidden?
91     boolean mWallpaperVisible;  // for wallpaper, what was last vis report?
92 
93     /**
94      * The window size that was requested by the application.  These are in
95      * the application's coordinate space (without compatibility scale applied).
96      */
97     int mRequestedWidth;
98     int mRequestedHeight;
99     int mLastRequestedWidth;
100     int mLastRequestedHeight;
101 
102     int mLayer;
103     boolean mHaveFrame;
104     boolean mObscured;
105     boolean mTurnOnScreen;
106 
107     int mLayoutSeq = -1;
108 
109     Configuration mConfiguration = null;
110 
111     /**
112      * Actual frame shown on-screen (may be modified by animation).  These
113      * are in the screen's coordinate space (WITH the compatibility scale
114      * applied).
115      */
116     final RectF mShownFrame = new RectF();
117 
118     /**
119      * Insets that determine the actually visible area.  These are in the application's
120      * coordinate space (without compatibility scale applied).
121      */
122     final Rect mVisibleInsets = new Rect();
123     final Rect mLastVisibleInsets = new Rect();
124     boolean mVisibleInsetsChanged;
125 
126     /**
127      * Insets that are covered by system windows (such as the status bar) and
128      * transient docking windows (such as the IME).  These are in the application's
129      * coordinate space (without compatibility scale applied).
130      */
131     final Rect mContentInsets = new Rect();
132     final Rect mLastContentInsets = new Rect();
133     boolean mContentInsetsChanged;
134 
135     /**
136      * Set to true if we are waiting for this window to receive its
137      * given internal insets before laying out other windows based on it.
138      */
139     boolean mGivenInsetsPending;
140 
141     /**
142      * These are the content insets that were given during layout for
143      * this window, to be applied to windows behind it.
144      */
145     final Rect mGivenContentInsets = new Rect();
146 
147     /**
148      * These are the visible insets that were given during layout for
149      * this window, to be applied to windows behind it.
150      */
151     final Rect mGivenVisibleInsets = new Rect();
152 
153     /**
154      * This is the given touchable area relative to the window frame, or null if none.
155      */
156     final Region mGivenTouchableRegion = new Region();
157 
158     /**
159      * Flag indicating whether the touchable region should be adjusted by
160      * the visible insets; if false the area outside the visible insets is
161      * NOT touchable, so we must use those to adjust the frame during hit
162      * tests.
163      */
164     int mTouchableInsets = ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME;
165 
166     /**
167      * This is rectangle of the window's surface that is not covered by
168      * system decorations.
169      */
170     final Rect mSystemDecorRect = new Rect();
171     final Rect mLastSystemDecorRect = new Rect();
172 
173     // Current transformation being applied.
174     float mGlobalScale=1;
175     float mInvGlobalScale=1;
176     float mHScale=1, mVScale=1;
177     float mLastHScale=1, mLastVScale=1;
178     final Matrix mTmpMatrix = new Matrix();
179 
180     // "Real" frame that the application sees, in display coordinate space.
181     final Rect mFrame = new Rect();
182     final Rect mLastFrame = new Rect();
183     // Frame that is scaled to the application's coordinate space when in
184     // screen size compatibility mode.
185     final Rect mCompatFrame = new Rect();
186 
187     final Rect mContainingFrame = new Rect();
188     final Rect mDisplayFrame = new Rect();
189     final Rect mContentFrame = new Rect();
190     final Rect mParentFrame = new Rect();
191     final Rect mVisibleFrame = new Rect();
192 
193     boolean mContentChanged;
194 
195     // If a window showing a wallpaper: the requested offset for the
196     // wallpaper; if a wallpaper window: the currently applied offset.
197     float mWallpaperX = -1;
198     float mWallpaperY = -1;
199 
200     // If a window showing a wallpaper: what fraction of the offset
201     // range corresponds to a full virtual screen.
202     float mWallpaperXStep = -1;
203     float mWallpaperYStep = -1;
204 
205     // Wallpaper windows: pixels offset based on above variables.
206     int mXOffset;
207     int mYOffset;
208 
209     // This is set after IWindowSession.relayout() has been called at
210     // least once for the window.  It allows us to detect the situation
211     // where we don't yet have a surface, but should have one soon, so
212     // we can give the window focus before waiting for the relayout.
213     boolean mRelayoutCalled;
214 
215     // If the application has called relayout() with changes that can
216     // impact its window's size, we need to perform a layout pass on it
217     // even if it is not currently visible for layout.  This is set
218     // when in that case until the layout is done.
219     boolean mLayoutNeeded;
220 
221     // Currently running an exit animation?
222     boolean mExiting;
223 
224     // Currently on the mDestroySurface list?
225     boolean mDestroying;
226 
227     // Completely remove from window manager after exit animation?
228     boolean mRemoveOnExit;
229 
230     // Set when the orientation is changing and this window has not yet
231     // been updated for the new orientation.
232     boolean mOrientationChanging;
233 
234     // Is this window now (or just being) removed?
235     boolean mRemoved;
236 
237     // Temp for keeping track of windows that have been removed when
238     // rebuilding window list.
239     boolean mRebuilding;
240 
241     // Input channel and input window handle used by the input dispatcher.
242     final InputWindowHandle mInputWindowHandle;
243     InputChannel mInputChannel;
244 
245     // Used to improve performance of toString()
246     String mStringNameCache;
247     CharSequence mLastTitle;
248     boolean mWasPaused;
249 
250     final WindowStateAnimator mWinAnimator;
251 
252     boolean mHasSurface = false;
253 
WindowState(WindowManagerService service, Session s, IWindow c, WindowToken token, WindowState attachedWindow, int seq, WindowManager.LayoutParams a, int viewVisibility)254     WindowState(WindowManagerService service, Session s, IWindow c, WindowToken token,
255            WindowState attachedWindow, int seq, WindowManager.LayoutParams a,
256            int viewVisibility) {
257         mService = service;
258         mSession = s;
259         mClient = c;
260         mToken = token;
261         mAttrs.copyFrom(a);
262         mViewVisibility = viewVisibility;
263         mPolicy = mService.mPolicy;
264         mContext = mService.mContext;
265         DeathRecipient deathRecipient = new DeathRecipient();
266         mSeq = seq;
267         mEnforceSizeCompat = (mAttrs.flags & FLAG_COMPATIBLE_WINDOW) != 0;
268         if (WindowManagerService.localLOGV) Slog.v(
269             TAG, "Window " + this + " client=" + c.asBinder()
270             + " token=" + token + " (" + mAttrs.token + ")");
271         try {
272             c.asBinder().linkToDeath(deathRecipient, 0);
273         } catch (RemoteException e) {
274             mDeathRecipient = null;
275             mAttachedWindow = null;
276             mLayoutAttached = false;
277             mIsImWindow = false;
278             mIsWallpaper = false;
279             mIsFloatingLayer = false;
280             mBaseLayer = 0;
281             mSubLayer = 0;
282             mInputWindowHandle = null;
283             mWinAnimator = null;
284             return;
285         }
286         mDeathRecipient = deathRecipient;
287 
288         if ((mAttrs.type >= FIRST_SUB_WINDOW &&
289                 mAttrs.type <= LAST_SUB_WINDOW)) {
290             // The multiplier here is to reserve space for multiple
291             // windows in the same type layer.
292             mBaseLayer = mPolicy.windowTypeToLayerLw(
293                     attachedWindow.mAttrs.type) * WindowManagerService.TYPE_LAYER_MULTIPLIER
294                     + WindowManagerService.TYPE_LAYER_OFFSET;
295             mSubLayer = mPolicy.subWindowTypeToLayerLw(a.type);
296             mAttachedWindow = attachedWindow;
297             if (WindowManagerService.DEBUG_ADD_REMOVE) Slog.v(TAG, "Adding " + this + " to " + mAttachedWindow);
298             mAttachedWindow.mChildWindows.add(this);
299             mLayoutAttached = mAttrs.type !=
300                     WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
301             mIsImWindow = attachedWindow.mAttrs.type == TYPE_INPUT_METHOD
302                     || attachedWindow.mAttrs.type == TYPE_INPUT_METHOD_DIALOG;
303             mIsWallpaper = attachedWindow.mAttrs.type == TYPE_WALLPAPER;
304             mIsFloatingLayer = mIsImWindow || mIsWallpaper;
305         } else {
306             // The multiplier here is to reserve space for multiple
307             // windows in the same type layer.
308             mBaseLayer = mPolicy.windowTypeToLayerLw(a.type)
309                     * WindowManagerService.TYPE_LAYER_MULTIPLIER
310                     + WindowManagerService.TYPE_LAYER_OFFSET;
311             mSubLayer = 0;
312             mAttachedWindow = null;
313             mLayoutAttached = false;
314             mIsImWindow = mAttrs.type == TYPE_INPUT_METHOD
315                     || mAttrs.type == TYPE_INPUT_METHOD_DIALOG;
316             mIsWallpaper = mAttrs.type == TYPE_WALLPAPER;
317             mIsFloatingLayer = mIsImWindow || mIsWallpaper;
318         }
319 
320         mWinAnimator = new WindowStateAnimator(service, this, mAttachedWindow);
321         mWinAnimator.mAlpha = a.alpha;
322 
323         WindowState appWin = this;
324         while (appWin.mAttachedWindow != null) {
325             appWin = appWin.mAttachedWindow;
326         }
327         WindowToken appToken = appWin.mToken;
328         while (appToken.appWindowToken == null) {
329             WindowToken parent = mService.mTokenMap.get(appToken.token);
330             if (parent == null || appToken == parent) {
331                 break;
332             }
333             appToken = parent;
334         }
335         mRootToken = appToken;
336         mAppToken = appToken.appWindowToken;
337 
338         mRequestedWidth = 0;
339         mRequestedHeight = 0;
340         mLastRequestedWidth = 0;
341         mLastRequestedHeight = 0;
342         mXOffset = 0;
343         mYOffset = 0;
344         mLayer = 0;
345         mInputWindowHandle = new InputWindowHandle(
346                 mAppToken != null ? mAppToken.mInputApplicationHandle : null, this);
347     }
348 
attach()349     void attach() {
350         if (WindowManagerService.localLOGV) Slog.v(
351             TAG, "Attaching " + this + " token=" + mToken
352             + ", list=" + mToken.windows);
353         mSession.windowAddedLocked();
354     }
355 
356     @Override
computeFrameLw(Rect pf, Rect df, Rect cf, Rect vf)357     public void computeFrameLw(Rect pf, Rect df, Rect cf, Rect vf) {
358         mHaveFrame = true;
359 
360         final Rect container = mContainingFrame;
361         container.set(pf);
362 
363         final Rect display = mDisplayFrame;
364         display.set(df);
365 
366         final int pw = container.right - container.left;
367         final int ph = container.bottom - container.top;
368 
369         int w,h;
370         if ((mAttrs.flags & WindowManager.LayoutParams.FLAG_SCALED) != 0) {
371             if (mAttrs.width < 0) {
372                 w = pw;
373             } else if (mEnforceSizeCompat) {
374                 w = (int)(mAttrs.width * mGlobalScale + .5f);
375             } else {
376                 w = mAttrs.width;
377             }
378             if (mAttrs.height < 0) {
379                 h = ph;
380             } else if (mEnforceSizeCompat) {
381                 h = (int)(mAttrs.height * mGlobalScale + .5f);
382             } else {
383                 h = mAttrs.height;
384             }
385         } else {
386             if (mAttrs.width == WindowManager.LayoutParams.MATCH_PARENT) {
387                 w = pw;
388             } else if (mEnforceSizeCompat) {
389                 w = (int)(mRequestedWidth * mGlobalScale + .5f);
390             } else {
391                 w = mRequestedWidth;
392             }
393             if (mAttrs.height == WindowManager.LayoutParams.MATCH_PARENT) {
394                 h = ph;
395             } else if (mEnforceSizeCompat) {
396                 h = (int)(mRequestedHeight * mGlobalScale + .5f);
397             } else {
398                 h = mRequestedHeight;
399             }
400         }
401 
402         if (!mParentFrame.equals(pf)) {
403             //Slog.i(TAG, "Window " + this + " content frame from " + mParentFrame
404             //        + " to " + pf);
405             mParentFrame.set(pf);
406             mContentChanged = true;
407         }
408         if (mRequestedWidth != mLastRequestedWidth || mRequestedHeight != mLastRequestedHeight) {
409             mLastRequestedWidth = mRequestedWidth;
410             mLastRequestedHeight = mRequestedHeight;
411             mContentChanged = true;
412         }
413 
414         final Rect content = mContentFrame;
415         content.set(cf);
416 
417         final Rect visible = mVisibleFrame;
418         visible.set(vf);
419 
420         final Rect frame = mFrame;
421         final int fw = frame.width();
422         final int fh = frame.height();
423 
424         //System.out.println("In: w=" + w + " h=" + h + " container=" +
425         //                   container + " x=" + mAttrs.x + " y=" + mAttrs.y);
426 
427         float x, y;
428         if (mEnforceSizeCompat) {
429             x = mAttrs.x * mGlobalScale;
430             y = mAttrs.y * mGlobalScale;
431         } else {
432             x = mAttrs.x;
433             y = mAttrs.y;
434         }
435 
436         Gravity.apply(mAttrs.gravity, w, h, container,
437                 (int) (x + mAttrs.horizontalMargin * pw),
438                 (int) (y + mAttrs.verticalMargin * ph), frame);
439 
440         //System.out.println("Out: " + mFrame);
441 
442         // Now make sure the window fits in the overall display.
443         Gravity.applyDisplay(mAttrs.gravity, df, frame);
444 
445         // Make sure the system, content and visible frames are inside of the
446         // final window frame.
447         if (content.left < frame.left) content.left = frame.left;
448         if (content.top < frame.top) content.top = frame.top;
449         if (content.right > frame.right) content.right = frame.right;
450         if (content.bottom > frame.bottom) content.bottom = frame.bottom;
451         if (visible.left < frame.left) visible.left = frame.left;
452         if (visible.top < frame.top) visible.top = frame.top;
453         if (visible.right > frame.right) visible.right = frame.right;
454         if (visible.bottom > frame.bottom) visible.bottom = frame.bottom;
455 
456         final Rect contentInsets = mContentInsets;
457         contentInsets.left = content.left-frame.left;
458         contentInsets.top = content.top-frame.top;
459         contentInsets.right = frame.right-content.right;
460         contentInsets.bottom = frame.bottom-content.bottom;
461 
462         final Rect visibleInsets = mVisibleInsets;
463         visibleInsets.left = visible.left-frame.left;
464         visibleInsets.top = visible.top-frame.top;
465         visibleInsets.right = frame.right-visible.right;
466         visibleInsets.bottom = frame.bottom-visible.bottom;
467 
468         mCompatFrame.set(frame);
469         if (mEnforceSizeCompat) {
470             // If there is a size compatibility scale being applied to the
471             // window, we need to apply this to its insets so that they are
472             // reported to the app in its coordinate space.
473             contentInsets.scale(mInvGlobalScale);
474             visibleInsets.scale(mInvGlobalScale);
475 
476             // Also the scaled frame that we report to the app needs to be
477             // adjusted to be in its coordinate space.
478             mCompatFrame.scale(mInvGlobalScale);
479         }
480 
481         if (mIsWallpaper && (fw != frame.width() || fh != frame.height())) {
482             mService.updateWallpaperOffsetLocked(this,
483                     mService.mAppDisplayWidth, mService.mAppDisplayHeight, false);
484         }
485 
486         if (WindowManagerService.localLOGV) {
487             //if ("com.google.android.youtube".equals(mAttrs.packageName)
488             //        && mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_PANEL) {
489                 Slog.v(TAG, "Resolving (mRequestedWidth="
490                         + mRequestedWidth + ", mRequestedheight="
491                         + mRequestedHeight + ") to" + " (pw=" + pw + ", ph=" + ph
492                         + "): frame=" + mFrame.toShortString()
493                         + " ci=" + contentInsets.toShortString()
494                         + " vi=" + visibleInsets.toShortString());
495             //}
496         }
497     }
498 
499     @Override
getFrameLw()500     public Rect getFrameLw() {
501         return mFrame;
502     }
503 
504     @Override
getShownFrameLw()505     public RectF getShownFrameLw() {
506         return mShownFrame;
507     }
508 
509     @Override
getDisplayFrameLw()510     public Rect getDisplayFrameLw() {
511         return mDisplayFrame;
512     }
513 
514     @Override
getContentFrameLw()515     public Rect getContentFrameLw() {
516         return mContentFrame;
517     }
518 
519     @Override
getVisibleFrameLw()520     public Rect getVisibleFrameLw() {
521         return mVisibleFrame;
522     }
523 
524     @Override
getGivenInsetsPendingLw()525     public boolean getGivenInsetsPendingLw() {
526         return mGivenInsetsPending;
527     }
528 
529     @Override
getGivenContentInsetsLw()530     public Rect getGivenContentInsetsLw() {
531         return mGivenContentInsets;
532     }
533 
534     @Override
getGivenVisibleInsetsLw()535     public Rect getGivenVisibleInsetsLw() {
536         return mGivenVisibleInsets;
537     }
538 
539     @Override
getAttrs()540     public WindowManager.LayoutParams getAttrs() {
541         return mAttrs;
542     }
543 
getNeedsMenuLw(WindowManagerPolicy.WindowState bottom)544     public boolean getNeedsMenuLw(WindowManagerPolicy.WindowState bottom) {
545         int index = -1;
546         WindowState ws = this;
547         while (true) {
548             if ((ws.mAttrs.privateFlags
549                     & WindowManager.LayoutParams.PRIVATE_FLAG_SET_NEEDS_MENU_KEY) != 0) {
550                 return (ws.mAttrs.flags & WindowManager.LayoutParams.FLAG_NEEDS_MENU_KEY) != 0;
551             }
552             // If we reached the bottom of the range of windows we are considering,
553             // assume no menu is needed.
554             if (ws == bottom) {
555                 return false;
556             }
557             // The current window hasn't specified whether menu key is needed;
558             // look behind it.
559             // First, we may need to determine the starting position.
560             if (index < 0) {
561                 index = mService.mWindows.indexOf(ws);
562             }
563             index--;
564             if (index < 0) {
565                 return false;
566             }
567             ws = mService.mWindows.get(index);
568         }
569     }
570 
getSystemUiVisibility()571     public int getSystemUiVisibility() {
572         return mSystemUiVisibility;
573     }
574 
getSurfaceLayer()575     public int getSurfaceLayer() {
576         return mLayer;
577     }
578 
getAppToken()579     public IApplicationToken getAppToken() {
580         return mAppToken != null ? mAppToken.appToken : null;
581     }
582 
getInputDispatchingTimeoutNanos()583     public long getInputDispatchingTimeoutNanos() {
584         return mAppToken != null
585                 ? mAppToken.inputDispatchingTimeoutNanos
586                 : WindowManagerService.DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS;
587     }
588 
hasAppShownWindows()589     public boolean hasAppShownWindows() {
590         return mAppToken != null && (mAppToken.firstWindowDrawn || mAppToken.startingDisplayed);
591     }
592 
isIdentityMatrix(float dsdx, float dtdx, float dsdy, float dtdy)593     boolean isIdentityMatrix(float dsdx, float dtdx, float dsdy, float dtdy) {
594         if (dsdx < .99999f || dsdx > 1.00001f) return false;
595         if (dtdy < .99999f || dtdy > 1.00001f) return false;
596         if (dtdx < -.000001f || dtdx > .000001f) return false;
597         if (dsdy < -.000001f || dsdy > .000001f) return false;
598         return true;
599     }
600 
prelayout()601     void prelayout() {
602         if (mEnforceSizeCompat) {
603             mGlobalScale = mService.mCompatibleScreenScale;
604             mInvGlobalScale = 1/mGlobalScale;
605         } else {
606             mGlobalScale = mInvGlobalScale = 1;
607         }
608     }
609 
610     /**
611      * Is this window visible?  It is not visible if there is no
612      * surface, or we are in the process of running an exit animation
613      * that will remove the surface, or its app token has been hidden.
614      */
isVisibleLw()615     public boolean isVisibleLw() {
616         final AppWindowToken atoken = mAppToken;
617         return mHasSurface && mPolicyVisibility && !mAttachedHidden
618                 && (atoken == null || !atoken.hiddenRequested)
619                 && !mExiting && !mDestroying;
620     }
621 
622     /**
623      * Like {@link #isVisibleLw}, but also counts a window that is currently
624      * "hidden" behind the keyguard as visible.  This allows us to apply
625      * things like window flags that impact the keyguard.
626      * XXX I am starting to think we need to have ANOTHER visibility flag
627      * for this "hidden behind keyguard" state rather than overloading
628      * mPolicyVisibility.  Ungh.
629      */
isVisibleOrBehindKeyguardLw()630     public boolean isVisibleOrBehindKeyguardLw() {
631         if (mRootToken.waitingToShow &&
632                 mService.mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
633             return false;
634         }
635         final AppWindowToken atoken = mAppToken;
636         final boolean animating = atoken != null
637                 ? (atoken.mAppAnimator.animation != null) : false;
638         return mHasSurface && !mDestroying && !mExiting
639                 && (atoken == null ? mPolicyVisibility : !atoken.hiddenRequested)
640                 && ((!mAttachedHidden && mViewVisibility == View.VISIBLE
641                                 && !mRootToken.hidden)
642                         || mWinAnimator.mAnimation != null || animating);
643     }
644 
645     /**
646      * Is this window visible, ignoring its app token?  It is not visible
647      * if there is no surface, or we are in the process of running an exit animation
648      * that will remove the surface.
649      */
isWinVisibleLw()650     public boolean isWinVisibleLw() {
651         final AppWindowToken atoken = mAppToken;
652         return mHasSurface && mPolicyVisibility && !mAttachedHidden
653                 && (atoken == null || !atoken.hiddenRequested || atoken.mAppAnimator.animating)
654                 && !mExiting && !mDestroying;
655     }
656 
657     /**
658      * The same as isVisible(), but follows the current hidden state of
659      * the associated app token, not the pending requested hidden state.
660      */
isVisibleNow()661     boolean isVisibleNow() {
662         return mHasSurface && mPolicyVisibility && !mAttachedHidden
663                 && !mRootToken.hidden && !mExiting && !mDestroying;
664     }
665 
666     /**
667      * Can this window possibly be a drag/drop target?  The test here is
668      * a combination of the above "visible now" with the check that the
669      * Input Manager uses when discarding windows from input consideration.
670      */
isPotentialDragTarget()671     boolean isPotentialDragTarget() {
672         return isVisibleNow() && !mRemoved
673                 && mInputChannel != null && mInputWindowHandle != null;
674     }
675 
676     /**
677      * Same as isVisible(), but we also count it as visible between the
678      * call to IWindowSession.add() and the first relayout().
679      */
isVisibleOrAdding()680     boolean isVisibleOrAdding() {
681         final AppWindowToken atoken = mAppToken;
682         return (mHasSurface || (!mRelayoutCalled && mViewVisibility == View.VISIBLE))
683                 && mPolicyVisibility && !mAttachedHidden
684                 && (atoken == null || !atoken.hiddenRequested)
685                 && !mExiting && !mDestroying;
686     }
687 
688     /**
689      * Is this window currently on-screen?  It is on-screen either if it
690      * is visible or it is currently running an animation before no longer
691      * being visible.
692      */
isOnScreen()693     boolean isOnScreen() {
694         if (!mHasSurface || !mPolicyVisibility || mDestroying) {
695             return false;
696         }
697         final AppWindowToken atoken = mAppToken;
698         if (atoken != null) {
699             return ((!mAttachedHidden && !atoken.hiddenRequested)
700                             || mWinAnimator.mAnimation != null || atoken.mAppAnimator.animation != null);
701         }
702         return !mAttachedHidden || mWinAnimator.mAnimation != null;
703     }
704 
705     /**
706      * Like isOnScreen(), but we don't return true if the window is part
707      * of a transition that has not yet been started.
708      */
isReadyForDisplay()709     boolean isReadyForDisplay() {
710         if (mRootToken.waitingToShow &&
711                 mService.mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
712             return false;
713         }
714         return mHasSurface && mPolicyVisibility && !mDestroying
715                 && ((!mAttachedHidden && mViewVisibility == View.VISIBLE
716                                 && !mRootToken.hidden)
717                         || mWinAnimator.mAnimation != null
718                         || ((mAppToken != null) && (mAppToken.mAppAnimator.animation != null)));
719     }
720 
721     /**
722      * Like isReadyForDisplay(), but ignores any force hiding of the window due
723      * to the keyguard.
724      */
isReadyForDisplayIgnoringKeyguard()725     boolean isReadyForDisplayIgnoringKeyguard() {
726         if (mRootToken.waitingToShow &&
727                 mService.mNextAppTransition != WindowManagerPolicy.TRANSIT_UNSET) {
728             return false;
729         }
730         final AppWindowToken atoken = mAppToken;
731         if (atoken == null && !mPolicyVisibility) {
732             // If this is not an app window, and the policy has asked to force
733             // hide, then we really do want to hide.
734             return false;
735         }
736         return mHasSurface && !mDestroying
737                 && ((!mAttachedHidden && mViewVisibility == View.VISIBLE
738                                 && !mRootToken.hidden)
739                         || mWinAnimator.mAnimation != null
740                         || ((atoken != null) && (atoken.mAppAnimator.animation != null)
741                                 && !mWinAnimator.isDummyAnimation()));
742     }
743 
744     /**
745      * Like isOnScreen, but returns false if the surface hasn't yet
746      * been drawn.
747      */
isDisplayedLw()748     public boolean isDisplayedLw() {
749         final AppWindowToken atoken = mAppToken;
750         return isDrawnLw() && mPolicyVisibility
751             && ((!mAttachedHidden &&
752                     (atoken == null || !atoken.hiddenRequested))
753                     || mWinAnimator.mAnimating);
754     }
755 
756     /**
757      * Return true if this window (or a window it is attached to, but not
758      * considering its app token) is currently animating.
759      */
isAnimatingLw()760     public boolean isAnimatingLw() {
761         return mWinAnimator.mAnimation != null;
762     }
763 
isGoneForLayoutLw()764     public boolean isGoneForLayoutLw() {
765         final AppWindowToken atoken = mAppToken;
766         return mViewVisibility == View.GONE
767                 || !mRelayoutCalled
768                 || (atoken == null && mRootToken.hidden)
769                 || (atoken != null && (atoken.hiddenRequested || atoken.hidden))
770                 || mAttachedHidden
771                 || mExiting || mDestroying;
772     }
773 
774     /**
775      * Returns true if the window has a surface that it has drawn a
776      * complete UI in to.
777      */
isDrawnLw()778     public boolean isDrawnLw() {
779         return mHasSurface && !mDestroying &&
780                 (mWinAnimator.mDrawState == WindowStateAnimator.READY_TO_SHOW
781                 || mWinAnimator.mDrawState == WindowStateAnimator.HAS_DRAWN);
782     }
783 
784     /**
785      * Return true if the window is opaque and fully drawn.  This indicates
786      * it may obscure windows behind it.
787      */
isOpaqueDrawn()788     boolean isOpaqueDrawn() {
789         return (mAttrs.format == PixelFormat.OPAQUE
790                         || mAttrs.type == TYPE_WALLPAPER)
791                 && isDrawnLw() && mWinAnimator.mAnimation == null
792                 && (mAppToken == null || mAppToken.mAppAnimator.animation == null);
793     }
794 
795     /**
796      * Return whether this window is wanting to have a translation
797      * animation applied to it for an in-progress move.  (Only makes
798      * sense to call from performLayoutAndPlaceSurfacesLockedInner().)
799      */
shouldAnimateMove()800     boolean shouldAnimateMove() {
801         return mContentChanged && !mExiting && !mWinAnimator.mLastHidden && mService.okToDisplay()
802                 && (mFrame.top != mLastFrame.top
803                         || mFrame.left != mLastFrame.left)
804                 && (mAttachedWindow == null || !mAttachedWindow.shouldAnimateMove());
805     }
806 
isFullscreen(int screenWidth, int screenHeight)807     boolean isFullscreen(int screenWidth, int screenHeight) {
808         return mFrame.left <= 0 && mFrame.top <= 0 &&
809                 mFrame.right >= screenWidth && mFrame.bottom >= screenHeight;
810     }
811 
removeLocked()812     void removeLocked() {
813         disposeInputChannel();
814 
815         if (mAttachedWindow != null) {
816             if (WindowManagerService.DEBUG_ADD_REMOVE) Slog.v(TAG, "Removing " + this + " from " + mAttachedWindow);
817             mAttachedWindow.mChildWindows.remove(this);
818         }
819         mWinAnimator.destroyDeferredSurfaceLocked();
820         mWinAnimator.destroySurfaceLocked();
821         mSession.windowRemovedLocked();
822         try {
823             mClient.asBinder().unlinkToDeath(mDeathRecipient, 0);
824         } catch (RuntimeException e) {
825             // Ignore if it has already been removed (usually because
826             // we are doing this as part of processing a death note.)
827         }
828     }
829 
setInputChannel(InputChannel inputChannel)830     void setInputChannel(InputChannel inputChannel) {
831         if (mInputChannel != null) {
832             throw new IllegalStateException("Window already has an input channel.");
833         }
834 
835         mInputChannel = inputChannel;
836         mInputWindowHandle.inputChannel = inputChannel;
837     }
838 
disposeInputChannel()839     void disposeInputChannel() {
840         if (mInputChannel != null) {
841             mService.mInputManager.unregisterInputChannel(mInputChannel);
842 
843             mInputChannel.dispose();
844             mInputChannel = null;
845         }
846 
847         mInputWindowHandle.inputChannel = null;
848     }
849 
850     private class DeathRecipient implements IBinder.DeathRecipient {
binderDied()851         public void binderDied() {
852             try {
853                 synchronized(mService.mWindowMap) {
854                     WindowState win = mService.windowForClientLocked(mSession, mClient, false);
855                     Slog.i(TAG, "WIN DEATH: " + win);
856                     if (win != null) {
857                         mService.removeWindowLocked(mSession, win);
858                     }
859                 }
860             } catch (IllegalArgumentException ex) {
861                 // This will happen if the window has already been
862                 // removed.
863             }
864         }
865     }
866 
867     /** Returns true if this window desires key events.
868      * TODO(cmautner): Is this the same as {@link WindowManagerService#canBeImeTarget}
869      */
canReceiveKeys()870     public final boolean canReceiveKeys() {
871         return     isVisibleOrAdding()
872                 && (mViewVisibility == View.VISIBLE)
873                 && ((mAttrs.flags & WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE) == 0);
874     }
875 
876     @Override
hasDrawnLw()877     public boolean hasDrawnLw() {
878         return mWinAnimator.mDrawState == WindowStateAnimator.HAS_DRAWN;
879     }
880 
881     @Override
showLw(boolean doAnimation)882     public boolean showLw(boolean doAnimation) {
883         return showLw(doAnimation, true);
884     }
885 
showLw(boolean doAnimation, boolean requestAnim)886     boolean showLw(boolean doAnimation, boolean requestAnim) {
887         if (mPolicyVisibility && mPolicyVisibilityAfterAnim) {
888             // Already showing.
889             return false;
890         }
891         if (DEBUG_VISIBILITY) Slog.v(TAG, "Policy visibility true: " + this);
892         if (doAnimation) {
893             if (DEBUG_VISIBILITY) Slog.v(TAG, "doAnimation: mPolicyVisibility="
894                     + mPolicyVisibility + " mAnimation=" + mWinAnimator.mAnimation);
895             if (!mService.okToDisplay()) {
896                 doAnimation = false;
897             } else if (mPolicyVisibility && mWinAnimator.mAnimation == null) {
898                 // Check for the case where we are currently visible and
899                 // not animating; we do not want to do animation at such a
900                 // point to become visible when we already are.
901                 doAnimation = false;
902             }
903         }
904         mPolicyVisibility = true;
905         mPolicyVisibilityAfterAnim = true;
906         if (doAnimation) {
907             mWinAnimator.applyAnimationLocked(WindowManagerPolicy.TRANSIT_ENTER, true);
908         }
909         if (requestAnim) {
910             mService.scheduleAnimationLocked();
911         }
912         return true;
913     }
914 
915     @Override
hideLw(boolean doAnimation)916     public boolean hideLw(boolean doAnimation) {
917         return hideLw(doAnimation, true);
918     }
919 
hideLw(boolean doAnimation, boolean requestAnim)920     boolean hideLw(boolean doAnimation, boolean requestAnim) {
921         if (doAnimation) {
922             if (!mService.okToDisplay()) {
923                 doAnimation = false;
924             }
925         }
926         boolean current = doAnimation ? mPolicyVisibilityAfterAnim
927                 : mPolicyVisibility;
928         if (!current) {
929             // Already hiding.
930             return false;
931         }
932         if (doAnimation) {
933             mWinAnimator.applyAnimationLocked(WindowManagerPolicy.TRANSIT_EXIT, false);
934             if (mWinAnimator.mAnimation == null) {
935                 doAnimation = false;
936             }
937         }
938         if (doAnimation) {
939             mPolicyVisibilityAfterAnim = false;
940         } else {
941             if (DEBUG_VISIBILITY) Slog.v(TAG, "Policy visibility false: " + this);
942             mPolicyVisibilityAfterAnim = false;
943             mPolicyVisibility = false;
944             // Window is no longer visible -- make sure if we were waiting
945             // for it to be displayed before enabling the display, that
946             // we allow the display to be enabled now.
947             mService.enableScreenIfNeededLocked();
948             if (mService.mCurrentFocus == this) {
949                 mService.mFocusMayChange = true;
950             }
951         }
952         if (requestAnim) {
953             mService.scheduleAnimationLocked();
954         }
955         return true;
956     }
957 
958     @Override
isAlive()959     public boolean isAlive() {
960         return mClient.asBinder().isBinderAlive();
961     }
962 
applyInsets(Region outRegion, Rect frame, Rect inset)963     private static void applyInsets(Region outRegion, Rect frame, Rect inset) {
964         outRegion.set(
965                 frame.left + inset.left, frame.top + inset.top,
966                 frame.right - inset.right, frame.bottom - inset.bottom);
967     }
968 
getTouchableRegion(Region outRegion)969     public void getTouchableRegion(Region outRegion) {
970         final Rect frame = mFrame;
971         switch (mTouchableInsets) {
972             default:
973             case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME:
974                 outRegion.set(frame);
975                 break;
976             case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_CONTENT:
977                 applyInsets(outRegion, frame, mGivenContentInsets);
978                 break;
979             case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_VISIBLE:
980                 applyInsets(outRegion, frame, mGivenVisibleInsets);
981                 break;
982             case ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION: {
983                 final Region givenTouchableRegion = mGivenTouchableRegion;
984                 outRegion.set(givenTouchableRegion);
985                 outRegion.translate(frame.left, frame.top);
986                 break;
987             }
988         }
989     }
990 
dump(PrintWriter pw, String prefix, boolean dumpAll)991     void dump(PrintWriter pw, String prefix, boolean dumpAll) {
992         pw.print(prefix); pw.print("mSession="); pw.print(mSession);
993                 pw.print(" mClient="); pw.println(mClient.asBinder());
994         pw.print(prefix); pw.print("mAttrs="); pw.println(mAttrs);
995         pw.print(prefix); pw.print("Requested w="); pw.print(mRequestedWidth);
996                 pw.print(" h="); pw.print(mRequestedHeight);
997                 pw.print(" mLayoutSeq="); pw.println(mLayoutSeq);
998         if (mRequestedWidth != mLastRequestedWidth || mRequestedHeight != mLastRequestedHeight) {
999             pw.print(prefix); pw.print("LastRequested w="); pw.print(mLastRequestedWidth);
1000                     pw.print(" h="); pw.println(mLastRequestedHeight);
1001         }
1002         if (mAttachedWindow != null || mLayoutAttached) {
1003             pw.print(prefix); pw.print("mAttachedWindow="); pw.print(mAttachedWindow);
1004                     pw.print(" mLayoutAttached="); pw.println(mLayoutAttached);
1005         }
1006         if (mIsImWindow || mIsWallpaper || mIsFloatingLayer) {
1007             pw.print(prefix); pw.print("mIsImWindow="); pw.print(mIsImWindow);
1008                     pw.print(" mIsWallpaper="); pw.print(mIsWallpaper);
1009                     pw.print(" mIsFloatingLayer="); pw.print(mIsFloatingLayer);
1010                     pw.print(" mWallpaperVisible="); pw.println(mWallpaperVisible);
1011         }
1012         if (dumpAll) {
1013             pw.print(prefix); pw.print("mBaseLayer="); pw.print(mBaseLayer);
1014                     pw.print(" mSubLayer="); pw.print(mSubLayer);
1015                     pw.print(" mAnimLayer="); pw.print(mLayer); pw.print("+");
1016                     pw.print((mTargetAppToken != null ?
1017                             mTargetAppToken.mAppAnimator.animLayerAdjustment
1018                           : (mAppToken != null ? mAppToken.mAppAnimator.animLayerAdjustment : 0)));
1019                     pw.print("="); pw.print(mWinAnimator.mAnimLayer);
1020                     pw.print(" mLastLayer="); pw.println(mWinAnimator.mLastLayer);
1021         }
1022         if (dumpAll) {
1023             pw.print(prefix); pw.print("mToken="); pw.println(mToken);
1024             pw.print(prefix); pw.print("mRootToken="); pw.println(mRootToken);
1025             if (mAppToken != null) {
1026                 pw.print(prefix); pw.print("mAppToken="); pw.println(mAppToken);
1027             }
1028             if (mTargetAppToken != null) {
1029                 pw.print(prefix); pw.print("mTargetAppToken="); pw.println(mTargetAppToken);
1030             }
1031             pw.print(prefix); pw.print("mViewVisibility=0x");
1032             pw.print(Integer.toHexString(mViewVisibility));
1033             pw.print(" mHaveFrame="); pw.print(mHaveFrame);
1034             pw.print(" mObscured="); pw.println(mObscured);
1035             pw.print(prefix); pw.print("mSeq="); pw.print(mSeq);
1036             pw.print(" mSystemUiVisibility=0x");
1037             pw.println(Integer.toHexString(mSystemUiVisibility));
1038         }
1039         if (!mPolicyVisibility || !mPolicyVisibilityAfterAnim || mAttachedHidden) {
1040             pw.print(prefix); pw.print("mPolicyVisibility=");
1041                     pw.print(mPolicyVisibility);
1042                     pw.print(" mPolicyVisibilityAfterAnim=");
1043                     pw.print(mPolicyVisibilityAfterAnim);
1044                     pw.print(" mAttachedHidden="); pw.println(mAttachedHidden);
1045         }
1046         if (!mRelayoutCalled || mLayoutNeeded) {
1047             pw.print(prefix); pw.print("mRelayoutCalled="); pw.print(mRelayoutCalled);
1048                     pw.print(" mLayoutNeeded="); pw.println(mLayoutNeeded);
1049         }
1050         if (mXOffset != 0 || mYOffset != 0) {
1051             pw.print(prefix); pw.print("Offsets x="); pw.print(mXOffset);
1052                     pw.print(" y="); pw.println(mYOffset);
1053         }
1054         if (dumpAll) {
1055             pw.print(prefix); pw.print("mGivenContentInsets=");
1056                     mGivenContentInsets.printShortString(pw);
1057                     pw.print(" mGivenVisibleInsets=");
1058                     mGivenVisibleInsets.printShortString(pw);
1059                     pw.println();
1060             if (mTouchableInsets != 0 || mGivenInsetsPending) {
1061                 pw.print(prefix); pw.print("mTouchableInsets="); pw.print(mTouchableInsets);
1062                         pw.print(" mGivenInsetsPending="); pw.println(mGivenInsetsPending);
1063             }
1064             pw.print(prefix); pw.print("mConfiguration="); pw.println(mConfiguration);
1065         }
1066         pw.print(prefix); pw.print("mHasSurface="); pw.print(mHasSurface);
1067                 pw.print(" mShownFrame="); mShownFrame.printShortString(pw); pw.println();
1068         if (dumpAll) {
1069             pw.print(prefix); pw.print("mFrame="); mFrame.printShortString(pw);
1070                     pw.print(" last="); mLastFrame.printShortString(pw);
1071                     pw.println();
1072             pw.print(prefix); pw.print("mSystemDecorRect="); mSystemDecorRect.printShortString(pw);
1073                     pw.print(" last="); mLastSystemDecorRect.printShortString(pw);
1074                     pw.println();
1075         }
1076         if (mEnforceSizeCompat) {
1077             pw.print(prefix); pw.print("mCompatFrame="); mCompatFrame.printShortString(pw);
1078                     pw.println();
1079         }
1080         if (dumpAll) {
1081             pw.print(prefix); pw.print("Frames: containing=");
1082                     mContainingFrame.printShortString(pw);
1083                     pw.print(" parent="); mParentFrame.printShortString(pw);
1084                     pw.print(" display="); mDisplayFrame.printShortString(pw);
1085                     pw.println();
1086             pw.print(prefix); pw.print("    content="); mContentFrame.printShortString(pw);
1087                     pw.print(" visible="); mVisibleFrame.printShortString(pw);
1088                     pw.println();
1089             pw.print(prefix); pw.print("Cur insets: content=");
1090                     mContentInsets.printShortString(pw);
1091                     pw.print(" visible="); mVisibleInsets.printShortString(pw);
1092                     pw.println();
1093             pw.print(prefix); pw.print("Lst insets: content=");
1094                     mLastContentInsets.printShortString(pw);
1095                     pw.print(" visible="); mLastVisibleInsets.printShortString(pw);
1096                     pw.println();
1097         }
1098         mWinAnimator.dump(pw, prefix, dumpAll);
1099         if (mExiting || mRemoveOnExit || mDestroying || mRemoved) {
1100             pw.print(prefix); pw.print("mExiting="); pw.print(mExiting);
1101                     pw.print(" mRemoveOnExit="); pw.print(mRemoveOnExit);
1102                     pw.print(" mDestroying="); pw.print(mDestroying);
1103                     pw.print(" mRemoved="); pw.println(mRemoved);
1104         }
1105         if (mOrientationChanging || mAppFreezing || mTurnOnScreen) {
1106             pw.print(prefix); pw.print("mOrientationChanging=");
1107                     pw.print(mOrientationChanging);
1108                     pw.print(" mAppFreezing="); pw.print(mAppFreezing);
1109                     pw.print(" mTurnOnScreen="); pw.println(mTurnOnScreen);
1110         }
1111         if (mHScale != 1 || mVScale != 1) {
1112             pw.print(prefix); pw.print("mHScale="); pw.print(mHScale);
1113                     pw.print(" mVScale="); pw.println(mVScale);
1114         }
1115         if (mWallpaperX != -1 || mWallpaperY != -1) {
1116             pw.print(prefix); pw.print("mWallpaperX="); pw.print(mWallpaperX);
1117                     pw.print(" mWallpaperY="); pw.println(mWallpaperY);
1118         }
1119         if (mWallpaperXStep != -1 || mWallpaperYStep != -1) {
1120             pw.print(prefix); pw.print("mWallpaperXStep="); pw.print(mWallpaperXStep);
1121                     pw.print(" mWallpaperYStep="); pw.println(mWallpaperYStep);
1122         }
1123     }
1124 
makeInputChannelName()1125     String makeInputChannelName() {
1126         return Integer.toHexString(System.identityHashCode(this))
1127             + " " + mAttrs.getTitle();
1128     }
1129 
1130     @Override
toString()1131     public String toString() {
1132         if (mStringNameCache == null || mLastTitle != mAttrs.getTitle()
1133                 || mWasPaused != mToken.paused) {
1134             mLastTitle = mAttrs.getTitle();
1135             mWasPaused = mToken.paused;
1136             mStringNameCache = "Window{" + Integer.toHexString(System.identityHashCode(this))
1137                     + " " + mLastTitle + " paused=" + mWasPaused + "}";
1138         }
1139         return mStringNameCache;
1140     }
1141 }
1142