1 /*
2  * Copyright (C) 2014 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.TYPE_APPLICATION_STARTING;
20 import static com.android.server.wm.WindowManagerService.DEBUG_ANIM;
21 import static com.android.server.wm.WindowManagerService.DEBUG_LAYERS;
22 import static com.android.server.wm.WindowManagerService.DEBUG_ORIENTATION;
23 import static com.android.server.wm.WindowManagerService.DEBUG_STARTING_WINDOW;
24 import static com.android.server.wm.WindowManagerService.DEBUG_SURFACE_TRACE;
25 import static com.android.server.wm.WindowManagerService.SHOW_TRANSACTIONS;
26 import static com.android.server.wm.WindowManagerService.DEBUG_VISIBILITY;
27 import static com.android.server.wm.WindowManagerService.SHOW_LIGHT_TRANSACTIONS;
28 import static com.android.server.wm.WindowManagerService.SHOW_SURFACE_ALLOC;
29 import static com.android.server.wm.WindowManagerService.localLOGV;
30 import static com.android.server.wm.WindowManagerService.LayoutFields.SET_ORIENTATION_CHANGE_COMPLETE;
31 import static com.android.server.wm.WindowManagerService.LayoutFields.SET_TURN_ON_SCREEN;
32 
33 import android.content.Context;
34 import android.graphics.Matrix;
35 import android.graphics.PixelFormat;
36 import android.graphics.Point;
37 import android.graphics.PointF;
38 import android.graphics.Rect;
39 import android.graphics.RectF;
40 import android.graphics.Region;
41 import android.os.Debug;
42 import android.os.RemoteException;
43 import android.util.Slog;
44 import android.view.Display;
45 import android.view.DisplayInfo;
46 import android.view.MagnificationSpec;
47 import android.view.Surface.OutOfResourcesException;
48 import android.view.SurfaceControl;
49 import android.view.SurfaceSession;
50 import android.view.View;
51 import android.view.WindowManager;
52 import android.view.WindowManagerPolicy;
53 import android.view.WindowManager.LayoutParams;
54 import android.view.animation.Animation;
55 import android.view.animation.AnimationSet;
56 import android.view.animation.AnimationUtils;
57 import android.view.animation.Transformation;
58 
59 import com.android.server.wm.WindowManagerService.H;
60 
61 import java.io.PrintWriter;
62 import java.util.ArrayList;
63 
64 /**
65  * Keep track of animations and surface operations for a single WindowState.
66  **/
67 class WindowStateAnimator {
68     static final String TAG = "WindowStateAnimator";
69 
70     // Unchanging local convenience fields.
71     final WindowManagerService mService;
72     final WindowState mWin;
73     final WindowStateAnimator mAttachedWinAnimator;
74     final WindowAnimator mAnimator;
75     AppWindowAnimator mAppAnimator;
76     final Session mSession;
77     final WindowManagerPolicy mPolicy;
78     final Context mContext;
79     final boolean mIsWallpaper;
80 
81     // Currently running animation.
82     boolean mAnimating;
83     boolean mLocalAnimating;
84     Animation mAnimation;
85     boolean mAnimationIsEntrance;
86     boolean mHasTransformation;
87     boolean mHasLocalTransformation;
88     final Transformation mTransformation = new Transformation();
89     boolean mWasAnimating;      // Were we animating going into the most recent animation step?
90     int mAnimLayer;
91     int mLastLayer;
92     long mAnimationStartTime;
93     long mLastAnimationTime;
94 
95     SurfaceControl mSurfaceControl;
96     SurfaceControl mPendingDestroySurface;
97 
98     /**
99      * Set when we have changed the size of the surface, to know that
100      * we must tell them application to resize (and thus redraw itself).
101      */
102     boolean mSurfaceResized;
103 
104     /**
105      * Set if the client has asked that the destroy of its surface be delayed
106      * until it explicitly says it is okay.
107      */
108     boolean mSurfaceDestroyDeferred;
109 
110     float mShownAlpha = 0;
111     float mAlpha = 0;
112     float mLastAlpha = 0;
113 
114     boolean mHasClipRect;
115     Rect mClipRect = new Rect();
116     Rect mTmpClipRect = new Rect();
117     Rect mLastClipRect = new Rect();
118 
119     // Used to save animation distances between the time they are calculated and when they are
120     // used.
121     int mAnimDw;
122     int mAnimDh;
123 
124     /** Is the next animation to be started a window move animation? */
125     boolean mAnimateMove = false;
126 
127     /** Are we currently running a window move animation? */
128     boolean mAnimatingMove = false;
129 
130     float mDsDx=1, mDtDx=0, mDsDy=0, mDtDy=1;
131     float mLastDsDx=1, mLastDtDx=0, mLastDsDy=0, mLastDtDy=1;
132 
133     boolean mHaveMatrix;
134 
135     // For debugging, this is the last information given to the surface flinger.
136     boolean mSurfaceShown;
137     float mSurfaceX, mSurfaceY;
138     float mSurfaceW, mSurfaceH;
139     int mSurfaceLayer;
140     float mSurfaceAlpha;
141 
142     // Set to true if, when the window gets displayed, it should perform
143     // an enter animation.
144     boolean mEnterAnimationPending;
145 
146     /** Used to indicate that this window is undergoing an enter animation. Used for system
147      * windows to make the callback to View.dispatchOnWindowShownCallback(). Set when the
148      * window is first added or shown, cleared when the callback has been made. */
149     boolean mEnteringAnimation;
150 
151     boolean mKeyguardGoingAwayAnimation;
152 
153     /** The pixel format of the underlying SurfaceControl */
154     int mSurfaceFormat;
155 
156     /** This is set when there is no Surface */
157     static final int NO_SURFACE = 0;
158     /** This is set after the Surface has been created but before the window has been drawn. During
159      * this time the surface is hidden. */
160     static final int DRAW_PENDING = 1;
161     /** This is set after the window has finished drawing for the first time but before its surface
162      * is shown.  The surface will be displayed when the next layout is run. */
163     static final int COMMIT_DRAW_PENDING = 2;
164     /** This is set during the time after the window's drawing has been committed, and before its
165      * surface is actually shown.  It is used to delay showing the surface until all windows in a
166      * token are ready to be shown. */
167     static final int READY_TO_SHOW = 3;
168     /** Set when the window has been shown in the screen the first time. */
169     static final int HAS_DRAWN = 4;
170 
171     private static final int SYSTEM_UI_FLAGS_LAYOUT_STABLE_FULLSCREEN =
172             View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
173 
drawStateToString()174     String drawStateToString() {
175         switch (mDrawState) {
176             case NO_SURFACE: return "NO_SURFACE";
177             case DRAW_PENDING: return "DRAW_PENDING";
178             case COMMIT_DRAW_PENDING: return "COMMIT_DRAW_PENDING";
179             case READY_TO_SHOW: return "READY_TO_SHOW";
180             case HAS_DRAWN: return "HAS_DRAWN";
181             default: return Integer.toString(mDrawState);
182         }
183     }
184     int mDrawState;
185 
186     /** Was this window last hidden? */
187     boolean mLastHidden;
188 
189     int mAttrType;
190 
WindowStateAnimator(final WindowState win)191     WindowStateAnimator(final WindowState win) {
192         final WindowManagerService service = win.mService;
193 
194         mService = service;
195         mAnimator = service.mAnimator;
196         mPolicy = service.mPolicy;
197         mContext = service.mContext;
198         final DisplayContent displayContent = win.getDisplayContent();
199         if (displayContent != null) {
200             final DisplayInfo displayInfo = displayContent.getDisplayInfo();
201             mAnimDw = displayInfo.appWidth;
202             mAnimDh = displayInfo.appHeight;
203         } else {
204             Slog.w(TAG, "WindowStateAnimator ctor: Display has been removed");
205             // This is checked on return and dealt with.
206         }
207 
208         mWin = win;
209         mAttachedWinAnimator = win.mAttachedWindow == null
210                 ? null : win.mAttachedWindow.mWinAnimator;
211         mAppAnimator = win.mAppToken == null ? null : win.mAppToken.mAppAnimator;
212         mSession = win.mSession;
213         mAttrType = win.mAttrs.type;
214         mIsWallpaper = win.mIsWallpaper;
215     }
216 
setAnimation(Animation anim, long startTime)217     public void setAnimation(Animation anim, long startTime) {
218         if (localLOGV) Slog.v(TAG, "Setting animation in " + this + ": " + anim);
219         mAnimating = false;
220         mLocalAnimating = false;
221         mAnimation = anim;
222         mAnimation.restrictDuration(WindowManagerService.MAX_ANIMATION_DURATION);
223         mAnimation.scaleCurrentDuration(mService.getWindowAnimationScaleLocked());
224         // Start out animation gone if window is gone, or visible if window is visible.
225         mTransformation.clear();
226         mTransformation.setAlpha(mLastHidden ? 0 : 1);
227         mHasLocalTransformation = true;
228         mAnimationStartTime = startTime;
229     }
230 
setAnimation(Animation anim)231     public void setAnimation(Animation anim) {
232         setAnimation(anim, -1);
233     }
234 
clearAnimation()235     public void clearAnimation() {
236         if (mAnimation != null) {
237             mAnimating = true;
238             mLocalAnimating = false;
239             mAnimation.cancel();
240             mAnimation = null;
241             mKeyguardGoingAwayAnimation = false;
242         }
243     }
244 
245     /** Is the window or its container currently animating? */
isAnimating()246     boolean isAnimating() {
247         return mAnimation != null
248                 || (mAttachedWinAnimator != null && mAttachedWinAnimator.mAnimation != null)
249                 || (mAppAnimator != null && mAppAnimator.isAnimating());
250     }
251 
252     /** Is the window animating the DummyAnimation? */
isDummyAnimation()253     boolean isDummyAnimation() {
254         return mAppAnimator != null
255                 && mAppAnimator.animation == AppWindowAnimator.sDummyAnimation;
256     }
257 
258     /** Is this window currently set to animate or currently animating? */
isWindowAnimating()259     boolean isWindowAnimating() {
260         return mAnimation != null;
261     }
262 
cancelExitAnimationForNextAnimationLocked()263     void cancelExitAnimationForNextAnimationLocked() {
264         if (mAnimation != null) {
265             mAnimation.cancel();
266             mAnimation = null;
267             mLocalAnimating = false;
268             destroySurfaceLocked();
269         }
270     }
271 
stepAnimation(long currentTime)272     private boolean stepAnimation(long currentTime) {
273         if ((mAnimation == null) || !mLocalAnimating) {
274             return false;
275         }
276         mTransformation.clear();
277         final boolean more = mAnimation.getTransformation(currentTime, mTransformation);
278         if (false && DEBUG_ANIM) Slog.v(
279             TAG, "Stepped animation in " + this +
280             ": more=" + more + ", xform=" + mTransformation);
281         return more;
282     }
283 
284     // This must be called while inside a transaction.  Returns true if
285     // there is more animation to run.
stepAnimationLocked(long currentTime)286     boolean stepAnimationLocked(long currentTime) {
287         final DisplayContent displayContent = mWin.getDisplayContent();
288         if (displayContent != null && mService.okToDisplay()) {
289             // We will run animations as long as the display isn't frozen.
290 
291             if (mWin.isDrawnLw() && mAnimation != null) {
292                 mHasTransformation = true;
293                 mHasLocalTransformation = true;
294                 if (!mLocalAnimating) {
295                     if (DEBUG_ANIM) Slog.v(
296                         TAG, "Starting animation in " + this +
297                         " @ " + currentTime + ": ww=" + mWin.mFrame.width() +
298                         " wh=" + mWin.mFrame.height() +
299                         " dw=" + mAnimDw + " dh=" + mAnimDh +
300                         " scale=" + mService.getWindowAnimationScaleLocked());
301                     final DisplayInfo displayInfo = displayContent.getDisplayInfo();
302                     if (mAnimateMove) {
303                         mAnimateMove = false;
304                         mAnimation.initialize(mWin.mFrame.width(), mWin.mFrame.height(),
305                                 mAnimDw, mAnimDh);
306                     } else {
307                         mAnimation.initialize(mWin.mFrame.width(), mWin.mFrame.height(),
308                                 displayInfo.appWidth, displayInfo.appHeight);
309                     }
310                     mAnimDw = displayInfo.appWidth;
311                     mAnimDh = displayInfo.appHeight;
312                     mAnimation.setStartTime(mAnimationStartTime != -1
313                             ? mAnimationStartTime
314                             : currentTime);
315                     mLocalAnimating = true;
316                     mAnimating = true;
317                 }
318                 if ((mAnimation != null) && mLocalAnimating) {
319                     mLastAnimationTime = currentTime;
320                     if (stepAnimation(currentTime)) {
321                         return true;
322                     }
323                 }
324                 if (DEBUG_ANIM) Slog.v(
325                     TAG, "Finished animation in " + this +
326                     " @ " + currentTime);
327                 //WindowManagerService.this.dump();
328             }
329             mHasLocalTransformation = false;
330             if ((!mLocalAnimating || mAnimationIsEntrance) && mAppAnimator != null
331                     && mAppAnimator.animation != null) {
332                 // When our app token is animating, we kind-of pretend like
333                 // we are as well.  Note the mLocalAnimating mAnimationIsEntrance
334                 // part of this check means that we will only do this if
335                 // our window is not currently exiting, or it is not
336                 // locally animating itself.  The idea being that one that
337                 // is exiting and doing a local animation should be removed
338                 // once that animation is done.
339                 mAnimating = true;
340                 mHasTransformation = true;
341                 mTransformation.clear();
342                 return false;
343             } else if (mHasTransformation) {
344                 // Little trick to get through the path below to act like
345                 // we have finished an animation.
346                 mAnimating = true;
347             } else if (isAnimating()) {
348                 mAnimating = true;
349             }
350         } else if (mAnimation != null) {
351             // If the display is frozen, and there is a pending animation,
352             // clear it and make sure we run the cleanup code.
353             mAnimating = true;
354         }
355 
356         if (!mAnimating && !mLocalAnimating) {
357             return false;
358         }
359 
360         // Done animating, clean up.
361         if (DEBUG_ANIM) Slog.v(
362             TAG, "Animation done in " + this + ": exiting=" + mWin.mExiting
363             + ", reportedVisible="
364             + (mWin.mAppToken != null ? mWin.mAppToken.reportedVisible : false));
365 
366         mAnimating = false;
367         mKeyguardGoingAwayAnimation = false;
368         mAnimatingMove = false;
369         mLocalAnimating = false;
370         if (mAnimation != null) {
371             mAnimation.cancel();
372             mAnimation = null;
373         }
374         if (mAnimator.mWindowDetachedWallpaper == mWin) {
375             mAnimator.mWindowDetachedWallpaper = null;
376         }
377         mAnimLayer = mWin.mLayer;
378         if (mWin.mIsImWindow) {
379             mAnimLayer += mService.mInputMethodAnimLayerAdjustment;
380         } else if (mIsWallpaper) {
381             mAnimLayer += mService.mWallpaperAnimLayerAdjustment;
382         }
383         if (DEBUG_LAYERS) Slog.v(TAG, "Stepping win " + this
384                 + " anim layer: " + mAnimLayer);
385         mHasTransformation = false;
386         mHasLocalTransformation = false;
387         if (mWin.mPolicyVisibility != mWin.mPolicyVisibilityAfterAnim) {
388             if (DEBUG_VISIBILITY) {
389                 Slog.v(TAG, "Policy visibility changing after anim in " + this + ": "
390                         + mWin.mPolicyVisibilityAfterAnim);
391             }
392             mWin.mPolicyVisibility = mWin.mPolicyVisibilityAfterAnim;
393             if (displayContent != null) {
394                 displayContent.layoutNeeded = true;
395             }
396             if (!mWin.mPolicyVisibility) {
397                 if (mService.mCurrentFocus == mWin) {
398                     if (WindowManagerService.DEBUG_FOCUS_LIGHT) Slog.i(TAG,
399                             "setAnimationLocked: setting mFocusMayChange true");
400                     mService.mFocusMayChange = true;
401                 }
402                 // Window is no longer visible -- make sure if we were waiting
403                 // for it to be displayed before enabling the display, that
404                 // we allow the display to be enabled now.
405                 mService.enableScreenIfNeededLocked();
406             }
407         }
408         mTransformation.clear();
409         if (mDrawState == HAS_DRAWN
410                 && mWin.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING
411                 && mWin.mAppToken != null
412                 && mWin.mAppToken.firstWindowDrawn
413                 && mWin.mAppToken.startingData != null) {
414             if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Finish starting "
415                     + mWin.mToken + ": first real window done animating");
416             mService.mFinishedStarting.add(mWin.mAppToken);
417             mService.mH.sendEmptyMessage(H.FINISHED_STARTING);
418         } else if (mAttrType == LayoutParams.TYPE_STATUS_BAR && mWin.mPolicyVisibility) {
419             // Upon completion of a not-visible to visible status bar animation a relayout is
420             // required.
421             if (displayContent != null) {
422                 displayContent.layoutNeeded = true;
423             }
424         }
425 
426         finishExit();
427         final int displayId = mWin.getDisplayId();
428         mAnimator.setPendingLayoutChanges(displayId, WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM);
429         if (WindowManagerService.DEBUG_LAYOUT_REPEATS) mService.debugLayoutRepeats(
430                 "WindowStateAnimator", mAnimator.getPendingLayoutChanges(displayId));
431 
432         if (mWin.mAppToken != null) {
433             mWin.mAppToken.updateReportedVisibilityLocked();
434         }
435 
436         return false;
437     }
438 
finishExit()439     void finishExit() {
440         if (WindowManagerService.DEBUG_ANIM) Slog.v(
441                 TAG, "finishExit in " + this
442                 + ": exiting=" + mWin.mExiting
443                 + " remove=" + mWin.mRemoveOnExit
444                 + " windowAnimating=" + isWindowAnimating());
445 
446         final int N = mWin.mChildWindows.size();
447         for (int i=0; i<N; i++) {
448             mWin.mChildWindows.get(i).mWinAnimator.finishExit();
449         }
450 
451         if (mEnteringAnimation && mWin.mAppToken == null) {
452             try {
453                 mEnteringAnimation = false;
454                 mWin.mClient.dispatchWindowShown();
455             } catch (RemoteException e) {
456             }
457         }
458 
459         if (!isWindowAnimating()) {
460             //TODO (multidisplay): Accessibility is supported only for the default display.
461             if (mService.mAccessibilityController != null
462                     && mWin.getDisplayId() == Display.DEFAULT_DISPLAY) {
463                 mService.mAccessibilityController.onSomeWindowResizedOrMovedLocked();
464             }
465         }
466 
467         if (!mWin.mExiting) {
468             return;
469         }
470 
471         if (isWindowAnimating()) {
472             return;
473         }
474 
475         if (WindowManagerService.localLOGV) Slog.v(
476                 TAG, "Exit animation finished in " + this
477                 + ": remove=" + mWin.mRemoveOnExit);
478         if (mSurfaceControl != null) {
479             mService.mDestroySurface.add(mWin);
480             mWin.mDestroying = true;
481             if (SHOW_TRANSACTIONS) WindowManagerService.logSurface(
482                 mWin, "HIDE (finishExit)", null);
483             hide();
484         }
485         mWin.mExiting = false;
486         if (mWin.mRemoveOnExit) {
487             mService.mPendingRemove.add(mWin);
488             mWin.mRemoveOnExit = false;
489         }
490         mService.hideWallpapersLocked(mWin);
491     }
492 
hide()493     void hide() {
494         if (!mLastHidden) {
495             //dump();
496             mLastHidden = true;
497             if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(mWin,
498                     "HIDE (performLayout)", null);
499             if (mSurfaceControl != null) {
500                 mSurfaceShown = false;
501                 try {
502                     mSurfaceControl.hide();
503                 } catch (RuntimeException e) {
504                     Slog.w(TAG, "Exception hiding surface in " + mWin);
505                 }
506             }
507         }
508     }
509 
finishDrawingLocked()510     boolean finishDrawingLocked() {
511         final boolean startingWindow =
512                 mWin.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
513         if (DEBUG_STARTING_WINDOW && startingWindow) {
514             Slog.v(TAG, "Finishing drawing window " + mWin + ": mDrawState="
515                     + drawStateToString());
516         }
517         if (mDrawState == DRAW_PENDING) {
518             if (DEBUG_SURFACE_TRACE || DEBUG_ANIM || SHOW_TRANSACTIONS || DEBUG_ORIENTATION)
519                 Slog.v(TAG, "finishDrawingLocked: mDrawState=COMMIT_DRAW_PENDING " + this + " in "
520                         + mSurfaceControl);
521             if (DEBUG_STARTING_WINDOW && startingWindow) {
522                 Slog.v(TAG, "Draw state now committed in " + mWin);
523             }
524             mDrawState = COMMIT_DRAW_PENDING;
525             return true;
526         }
527         return false;
528     }
529 
530     // This must be called while inside a transaction.
commitFinishDrawingLocked()531     boolean commitFinishDrawingLocked() {
532         if (DEBUG_STARTING_WINDOW &&
533                 mWin.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING) {
534             Slog.i(TAG, "commitFinishDrawingLocked: " + mWin + " cur mDrawState="
535                     + drawStateToString());
536         }
537         if (mDrawState != COMMIT_DRAW_PENDING && mDrawState != READY_TO_SHOW) {
538             return false;
539         }
540         if (DEBUG_SURFACE_TRACE || DEBUG_ANIM) {
541             Slog.i(TAG, "commitFinishDrawingLocked: mDrawState=READY_TO_SHOW " + mSurfaceControl);
542         }
543         mDrawState = READY_TO_SHOW;
544         final AppWindowToken atoken = mWin.mAppToken;
545         if (atoken == null || atoken.allDrawn || mWin.mAttrs.type == TYPE_APPLICATION_STARTING) {
546             return performShowLocked();
547         }
548         return false;
549     }
550 
551     static class SurfaceTrace extends SurfaceControl {
552         private final static String SURFACE_TAG = "SurfaceTrace";
553         private final static boolean logSurfaceTrace = DEBUG_SURFACE_TRACE;
554         final static ArrayList<SurfaceTrace> sSurfaces = new ArrayList<SurfaceTrace>();
555 
556         private float mSurfaceTraceAlpha = 0;
557         private int mLayer;
558         private final PointF mPosition = new PointF();
559         private final Point mSize = new Point();
560         private final Rect mWindowCrop = new Rect();
561         private boolean mShown = false;
562         private int mLayerStack;
563         private boolean mIsOpaque;
564         private float mDsdx, mDtdx, mDsdy, mDtdy;
565         private final String mName;
566 
SurfaceTrace(SurfaceSession s, String name, int w, int h, int format, int flags)567         public SurfaceTrace(SurfaceSession s,
568                        String name, int w, int h, int format, int flags)
569                    throws OutOfResourcesException {
570             super(s, name, w, h, format, flags);
571             mName = name != null ? name : "Not named";
572             mSize.set(w, h);
573             if (logSurfaceTrace) Slog.v(SURFACE_TAG, "ctor: " + this + ". Called by "
574                     + Debug.getCallers(3));
575             synchronized (sSurfaces) {
576                 sSurfaces.add(0, this);
577             }
578         }
579 
580         @Override
setAlpha(float alpha)581         public void setAlpha(float alpha) {
582             if (mSurfaceTraceAlpha != alpha) {
583                 if (logSurfaceTrace) Slog.v(SURFACE_TAG, "setAlpha(" + alpha + "): OLD:" + this +
584                         ". Called by " + Debug.getCallers(3));
585                 mSurfaceTraceAlpha = alpha;
586             }
587             super.setAlpha(alpha);
588         }
589 
590         @Override
setLayer(int zorder)591         public void setLayer(int zorder) {
592             if (zorder != mLayer) {
593                 if (logSurfaceTrace) Slog.v(SURFACE_TAG, "setLayer(" + zorder + "): OLD:" + this
594                         + ". Called by " + Debug.getCallers(3));
595                 mLayer = zorder;
596             }
597             super.setLayer(zorder);
598 
599             synchronized (sSurfaces) {
600                 sSurfaces.remove(this);
601                 int i;
602                 for (i = sSurfaces.size() - 1; i >= 0; i--) {
603                     SurfaceTrace s = sSurfaces.get(i);
604                     if (s.mLayer < zorder) {
605                         break;
606                     }
607                 }
608                 sSurfaces.add(i + 1, this);
609             }
610         }
611 
612         @Override
setPosition(float x, float y)613         public void setPosition(float x, float y) {
614             if (x != mPosition.x || y != mPosition.y) {
615                 if (logSurfaceTrace) Slog.v(SURFACE_TAG, "setPosition(" + x + "," + y + "): OLD:"
616                         + this + ". Called by " + Debug.getCallers(3));
617                 mPosition.set(x, y);
618             }
619             super.setPosition(x, y);
620         }
621 
622         @Override
setSize(int w, int h)623         public void setSize(int w, int h) {
624             if (w != mSize.x || h != mSize.y) {
625                 if (logSurfaceTrace) Slog.v(SURFACE_TAG, "setSize(" + w + "," + h + "): OLD:"
626                         + this + ". Called by " + Debug.getCallers(3));
627                 mSize.set(w, h);
628             }
629             super.setSize(w, h);
630         }
631 
632         @Override
setWindowCrop(Rect crop)633         public void setWindowCrop(Rect crop) {
634             if (crop != null) {
635                 if (!crop.equals(mWindowCrop)) {
636                     if (logSurfaceTrace) Slog.v(SURFACE_TAG, "setWindowCrop("
637                             + crop.toShortString() + "): OLD:" + this + ". Called by "
638                             + Debug.getCallers(3));
639                     mWindowCrop.set(crop);
640                 }
641             }
642             super.setWindowCrop(crop);
643         }
644 
645         @Override
setLayerStack(int layerStack)646         public void setLayerStack(int layerStack) {
647             if (layerStack != mLayerStack) {
648                 if (logSurfaceTrace) Slog.v(SURFACE_TAG, "setLayerStack(" + layerStack + "): OLD:"
649                         + this + ". Called by " + Debug.getCallers(3));
650                 mLayerStack = layerStack;
651             }
652             super.setLayerStack(layerStack);
653         }
654 
655         @Override
setOpaque(boolean isOpaque)656         public void setOpaque(boolean isOpaque) {
657             if (isOpaque != mIsOpaque) {
658                 if (logSurfaceTrace) Slog.v(SURFACE_TAG, "setOpaque(" + isOpaque + "): OLD:"
659                         + this + ". Called by " + Debug.getCallers(3));
660                 mIsOpaque = isOpaque;
661             }
662             super.setOpaque(isOpaque);
663         }
664 
665         @Override
setSecure(boolean isSecure)666         public void setSecure(boolean isSecure) {
667             super.setSecure(isSecure);
668         }
669 
670         @Override
setMatrix(float dsdx, float dtdx, float dsdy, float dtdy)671         public void setMatrix(float dsdx, float dtdx, float dsdy, float dtdy) {
672             if (dsdx != mDsdx || dtdx != mDtdx || dsdy != mDsdy || dtdy != mDtdy) {
673                 if (logSurfaceTrace) Slog.v(SURFACE_TAG, "setMatrix(" + dsdx + "," + dtdx + ","
674                         + dsdy + "," + dtdy + "): OLD:" + this + ". Called by "
675                         + Debug.getCallers(3));
676                 mDsdx = dsdx;
677                 mDtdx = dtdx;
678                 mDsdy = dsdy;
679                 mDtdy = dtdy;
680             }
681             super.setMatrix(dsdx, dtdx, dsdy, dtdy);
682         }
683 
684         @Override
hide()685         public void hide() {
686             if (mShown) {
687                 if (logSurfaceTrace) Slog.v(SURFACE_TAG, "hide: OLD:" + this + ". Called by "
688                         + Debug.getCallers(3));
689                 mShown = false;
690             }
691             super.hide();
692         }
693 
694         @Override
show()695         public void show() {
696             if (!mShown) {
697                 if (logSurfaceTrace) Slog.v(SURFACE_TAG, "show: OLD:" + this + ". Called by "
698                         + Debug.getCallers(3));
699                 mShown = true;
700             }
701             super.show();
702         }
703 
704         @Override
destroy()705         public void destroy() {
706             super.destroy();
707             if (logSurfaceTrace) Slog.v(SURFACE_TAG, "destroy: " + this + ". Called by "
708                     + Debug.getCallers(3));
709             synchronized (sSurfaces) {
710                 sSurfaces.remove(this);
711             }
712         }
713 
714         @Override
release()715         public void release() {
716             super.release();
717             if (logSurfaceTrace) Slog.v(SURFACE_TAG, "release: " + this + ". Called by "
718                     + Debug.getCallers(3));
719             synchronized (sSurfaces) {
720                 sSurfaces.remove(this);
721             }
722         }
723 
dumpAllSurfaces(PrintWriter pw, String header)724         static void dumpAllSurfaces(PrintWriter pw, String header) {
725             synchronized (sSurfaces) {
726                 final int N = sSurfaces.size();
727                 if (N <= 0) {
728                     return;
729                 }
730                 if (header != null) {
731                     pw.println(header);
732                 }
733                 pw.println("WINDOW MANAGER SURFACES (dumpsys window surfaces)");
734                 for (int i = 0; i < N; i++) {
735                     SurfaceTrace s = sSurfaces.get(i);
736                     pw.print("  Surface #"); pw.print(i); pw.print(": #");
737                             pw.print(Integer.toHexString(System.identityHashCode(s)));
738                             pw.print(" "); pw.println(s.mName);
739                     pw.print("    mLayerStack="); pw.print(s.mLayerStack);
740                             pw.print(" mLayer="); pw.println(s.mLayer);
741                     pw.print("    mShown="); pw.print(s.mShown); pw.print(" mAlpha=");
742                             pw.print(s.mSurfaceTraceAlpha); pw.print(" mIsOpaque=");
743                             pw.println(s.mIsOpaque);
744                     pw.print("    mPosition="); pw.print(s.mPosition.x); pw.print(",");
745                             pw.print(s.mPosition.y);
746                             pw.print(" mSize="); pw.print(s.mSize.x); pw.print("x");
747                             pw.println(s.mSize.y);
748                     pw.print("    mCrop="); s.mWindowCrop.printShortString(pw); pw.println();
749                     pw.print("    Transform: ("); pw.print(s.mDsdx); pw.print(", ");
750                             pw.print(s.mDtdx); pw.print(", "); pw.print(s.mDsdy);
751                             pw.print(", "); pw.print(s.mDtdy); pw.println(")");
752                 }
753             }
754         }
755 
756         @Override
toString()757         public String toString() {
758             return "Surface " + Integer.toHexString(System.identityHashCode(this)) + " "
759                     + mName + " (" + mLayerStack + "): shown=" + mShown + " layer=" + mLayer
760                     + " alpha=" + mSurfaceTraceAlpha + " " + mPosition.x + "," + mPosition.y
761                     + " " + mSize.x + "x" + mSize.y
762                     + " crop=" + mWindowCrop.toShortString()
763                     + " opaque=" + mIsOpaque
764                     + " (" + mDsdx + "," + mDtdx + "," + mDsdy + "," + mDtdy + ")";
765         }
766     }
767 
createSurfaceLocked()768     SurfaceControl createSurfaceLocked() {
769         final WindowState w = mWin;
770         if (mSurfaceControl == null) {
771             if (DEBUG_ANIM || DEBUG_ORIENTATION) Slog.i(TAG,
772                     "createSurface " + this + ": mDrawState=DRAW_PENDING");
773             mDrawState = DRAW_PENDING;
774             if (w.mAppToken != null) {
775                 if (w.mAppToken.mAppAnimator.animation == null) {
776                     w.mAppToken.allDrawn = false;
777                     w.mAppToken.deferClearAllDrawn = false;
778                 } else {
779                     // Currently animating, persist current state of allDrawn until animation
780                     // is complete.
781                     w.mAppToken.deferClearAllDrawn = true;
782                 }
783             }
784 
785             mService.makeWindowFreezingScreenIfNeededLocked(w);
786 
787             int flags = SurfaceControl.HIDDEN;
788             final WindowManager.LayoutParams attrs = w.mAttrs;
789 
790             if (mService.isSecureLocked(w)) {
791                 flags |= SurfaceControl.SECURE;
792             }
793 
794             int width;
795             int height;
796             if ((attrs.flags & LayoutParams.FLAG_SCALED) != 0) {
797                 // for a scaled surface, we always want the requested
798                 // size.
799                 width = w.mRequestedWidth;
800                 height = w.mRequestedHeight;
801             } else {
802                 width = w.mCompatFrame.width();
803                 height = w.mCompatFrame.height();
804             }
805 
806             // Something is wrong and SurfaceFlinger will not like this,
807             // try to revert to sane values
808             if (width <= 0) {
809                 width = 1;
810             }
811             if (height <= 0) {
812                 height = 1;
813             }
814 
815             float left = w.mFrame.left + w.mXOffset;
816             float top = w.mFrame.top + w.mYOffset;
817 
818             // Adjust for surface insets.
819             width += attrs.surfaceInsets.left + attrs.surfaceInsets.right;
820             height += attrs.surfaceInsets.top + attrs.surfaceInsets.bottom;
821             left -= attrs.surfaceInsets.left;
822             top -= attrs.surfaceInsets.top;
823 
824             if (DEBUG_VISIBILITY) {
825                 Slog.v(TAG, "Creating surface in session "
826                         + mSession.mSurfaceSession + " window " + this
827                         + " w=" + width + " h=" + height
828                         + " x=" + left + " y=" + top
829                         + " format=" + attrs.format + " flags=" + flags);
830             }
831 
832             // We may abort, so initialize to defaults.
833             mSurfaceShown = false;
834             mSurfaceLayer = 0;
835             mSurfaceAlpha = 0;
836             mSurfaceX = 0;
837             mSurfaceY = 0;
838             w.mLastSystemDecorRect.set(0, 0, 0, 0);
839             mHasClipRect = false;
840             mClipRect.set(0, 0, 0, 0);
841             mLastClipRect.set(0, 0, 0, 0);
842 
843             // Set up surface control with initial size.
844             try {
845                 mSurfaceW = width;
846                 mSurfaceH = height;
847 
848                 final boolean isHwAccelerated = (attrs.flags &
849                         WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED) != 0;
850                 final int format = isHwAccelerated ? PixelFormat.TRANSLUCENT : attrs.format;
851                 if (!PixelFormat.formatHasAlpha(attrs.format)
852                         && attrs.surfaceInsets.left == 0
853                         && attrs.surfaceInsets.top == 0
854                         && attrs.surfaceInsets.right == 0
855                         && attrs.surfaceInsets.bottom  == 0) {
856                     flags |= SurfaceControl.OPAQUE;
857                 }
858 
859                 mSurfaceFormat = format;
860                 if (DEBUG_SURFACE_TRACE) {
861                     mSurfaceControl = new SurfaceTrace(
862                             mSession.mSurfaceSession,
863                             attrs.getTitle().toString(),
864                             width, height, format, flags);
865                 } else {
866                     mSurfaceControl = new SurfaceControl(
867                         mSession.mSurfaceSession,
868                         attrs.getTitle().toString(),
869                         width, height, format, flags);
870                 }
871 
872                 w.mHasSurface = true;
873 
874                 if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) {
875                     Slog.i(TAG, "  CREATE SURFACE "
876                             + mSurfaceControl + " IN SESSION "
877                             + mSession.mSurfaceSession
878                             + ": pid=" + mSession.mPid + " format="
879                             + attrs.format + " flags=0x"
880                             + Integer.toHexString(flags)
881                             + " / " + this);
882                 }
883             } catch (OutOfResourcesException e) {
884                 w.mHasSurface = false;
885                 Slog.w(TAG, "OutOfResourcesException creating surface");
886                 mService.reclaimSomeSurfaceMemoryLocked(this, "create", true);
887                 mDrawState = NO_SURFACE;
888                 return null;
889             } catch (Exception e) {
890                 w.mHasSurface = false;
891                 Slog.e(TAG, "Exception creating surface", e);
892                 mDrawState = NO_SURFACE;
893                 return null;
894             }
895 
896             if (WindowManagerService.localLOGV) {
897                 Slog.v(TAG, "Got surface: " + mSurfaceControl
898                         + ", set left=" + w.mFrame.left + " top=" + w.mFrame.top
899                         + ", animLayer=" + mAnimLayer);
900             }
901 
902             if (SHOW_LIGHT_TRANSACTIONS) {
903                 Slog.i(TAG, ">>> OPEN TRANSACTION createSurfaceLocked");
904                 WindowManagerService.logSurface(w, "CREATE pos=("
905                         + w.mFrame.left + "," + w.mFrame.top + ") ("
906                         + w.mCompatFrame.width() + "x" + w.mCompatFrame.height()
907                         + "), layer=" + mAnimLayer + " HIDE", null);
908             }
909 
910             // Start a new transaction and apply position & offset.
911             SurfaceControl.openTransaction();
912             try {
913                 mSurfaceX = left;
914                 mSurfaceY = top;
915 
916                 try {
917                     mSurfaceControl.setPosition(left, top);
918                     mSurfaceLayer = mAnimLayer;
919                     final DisplayContent displayContent = w.getDisplayContent();
920                     if (displayContent != null) {
921                         mSurfaceControl.setLayerStack(displayContent.getDisplay().getLayerStack());
922                     }
923                     mSurfaceControl.setLayer(mAnimLayer);
924                     mSurfaceControl.setAlpha(0);
925                     mSurfaceShown = false;
926                 } catch (RuntimeException e) {
927                     Slog.w(TAG, "Error creating surface in " + w, e);
928                     mService.reclaimSomeSurfaceMemoryLocked(this, "create-init", true);
929                 }
930                 mLastHidden = true;
931             } finally {
932                 SurfaceControl.closeTransaction();
933                 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
934                         "<<< CLOSE TRANSACTION createSurfaceLocked");
935             }
936             if (WindowManagerService.localLOGV) Slog.v(
937                     TAG, "Created surface " + this);
938         }
939         return mSurfaceControl;
940     }
941 
destroySurfaceLocked()942     void destroySurfaceLocked() {
943         if (mWin.mAppToken != null && mWin == mWin.mAppToken.startingWindow) {
944             mWin.mAppToken.startingDisplayed = false;
945         }
946 
947         if (mSurfaceControl != null) {
948 
949             int i = mWin.mChildWindows.size();
950             while (i > 0) {
951                 i--;
952                 WindowState c = mWin.mChildWindows.get(i);
953                 c.mAttachedHidden = true;
954             }
955 
956             try {
957                 if (DEBUG_VISIBILITY) {
958                     RuntimeException e = null;
959                     if (!WindowManagerService.HIDE_STACK_CRAWLS) {
960                         e = new RuntimeException();
961                         e.fillInStackTrace();
962                     }
963                     Slog.w(TAG, "Window " + this + " destroying surface "
964                             + mSurfaceControl + ", session " + mSession, e);
965                 }
966                 if (mSurfaceDestroyDeferred) {
967                     if (mSurfaceControl != null && mPendingDestroySurface != mSurfaceControl) {
968                         if (mPendingDestroySurface != null) {
969                             if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) {
970                                 RuntimeException e = null;
971                                 if (!WindowManagerService.HIDE_STACK_CRAWLS) {
972                                     e = new RuntimeException();
973                                     e.fillInStackTrace();
974                                 }
975                                 WindowManagerService.logSurface(mWin, "DESTROY PENDING", e);
976                             }
977                             mPendingDestroySurface.destroy();
978                         }
979                         mPendingDestroySurface = mSurfaceControl;
980                     }
981                 } else {
982                     if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) {
983                         RuntimeException e = null;
984                         if (!WindowManagerService.HIDE_STACK_CRAWLS) {
985                             e = new RuntimeException();
986                             e.fillInStackTrace();
987                         }
988                         WindowManagerService.logSurface(mWin, "DESTROY", e);
989                     }
990                     mSurfaceControl.destroy();
991                 }
992                 mService.hideWallpapersLocked(mWin);
993             } catch (RuntimeException e) {
994                 Slog.w(TAG, "Exception thrown when destroying Window " + this
995                     + " surface " + mSurfaceControl + " session " + mSession
996                     + ": " + e.toString());
997             }
998 
999             mSurfaceShown = false;
1000             mSurfaceControl = null;
1001             mWin.mHasSurface = false;
1002             mDrawState = NO_SURFACE;
1003         }
1004     }
1005 
destroyDeferredSurfaceLocked()1006     void destroyDeferredSurfaceLocked() {
1007         try {
1008             if (mPendingDestroySurface != null) {
1009                 if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) {
1010                     RuntimeException e = null;
1011                     if (!WindowManagerService.HIDE_STACK_CRAWLS) {
1012                         e = new RuntimeException();
1013                         e.fillInStackTrace();
1014                     }
1015                     WindowManagerService.logSurface(mWin, "DESTROY PENDING", e);
1016                 }
1017                 mPendingDestroySurface.destroy();
1018                 mService.hideWallpapersLocked(mWin);
1019             }
1020         } catch (RuntimeException e) {
1021             Slog.w(TAG, "Exception thrown when destroying Window "
1022                     + this + " surface " + mPendingDestroySurface
1023                     + " session " + mSession + ": " + e.toString());
1024         }
1025         mSurfaceDestroyDeferred = false;
1026         mPendingDestroySurface = null;
1027     }
1028 
computeShownFrameLocked()1029     void computeShownFrameLocked() {
1030         final boolean selfTransformation = mHasLocalTransformation;
1031         Transformation attachedTransformation =
1032                 (mAttachedWinAnimator != null && mAttachedWinAnimator.mHasLocalTransformation)
1033                 ? mAttachedWinAnimator.mTransformation : null;
1034         Transformation appTransformation = (mAppAnimator != null && mAppAnimator.hasTransformation)
1035                 ? mAppAnimator.transformation : null;
1036 
1037         // Wallpapers are animated based on the "real" window they
1038         // are currently targeting.
1039         final WindowState wallpaperTarget = mService.mWallpaperTarget;
1040         if (mIsWallpaper && wallpaperTarget != null && mService.mAnimateWallpaperWithTarget) {
1041             final WindowStateAnimator wallpaperAnimator = wallpaperTarget.mWinAnimator;
1042             if (wallpaperAnimator.mHasLocalTransformation &&
1043                     wallpaperAnimator.mAnimation != null &&
1044                     !wallpaperAnimator.mAnimation.getDetachWallpaper()) {
1045                 attachedTransformation = wallpaperAnimator.mTransformation;
1046                 if (WindowManagerService.DEBUG_WALLPAPER && attachedTransformation != null) {
1047                     Slog.v(TAG, "WP target attached xform: " + attachedTransformation);
1048                 }
1049             }
1050             final AppWindowAnimator wpAppAnimator = wallpaperTarget.mAppToken == null ?
1051                     null : wallpaperTarget.mAppToken.mAppAnimator;
1052                 if (wpAppAnimator != null && wpAppAnimator.hasTransformation
1053                     && wpAppAnimator.animation != null
1054                     && !wpAppAnimator.animation.getDetachWallpaper()) {
1055                 appTransformation = wpAppAnimator.transformation;
1056                 if (WindowManagerService.DEBUG_WALLPAPER && appTransformation != null) {
1057                     Slog.v(TAG, "WP target app xform: " + appTransformation);
1058                 }
1059             }
1060         }
1061 
1062         final int displayId = mWin.getDisplayId();
1063         final ScreenRotationAnimation screenRotationAnimation =
1064                 mAnimator.getScreenRotationAnimationLocked(displayId);
1065         final boolean screenAnimation =
1066                 screenRotationAnimation != null && screenRotationAnimation.isAnimating();
1067         if (selfTransformation || attachedTransformation != null
1068                 || appTransformation != null || screenAnimation) {
1069             // cache often used attributes locally
1070             final Rect frame = mWin.mFrame;
1071             final float tmpFloats[] = mService.mTmpFloats;
1072             final Matrix tmpMatrix = mWin.mTmpMatrix;
1073 
1074             // Compute the desired transformation.
1075             if (screenAnimation && screenRotationAnimation.isRotating()) {
1076                 // If we are doing a screen animation, the global rotation
1077                 // applied to windows can result in windows that are carefully
1078                 // aligned with each other to slightly separate, allowing you
1079                 // to see what is behind them.  An unsightly mess.  This...
1080                 // thing...  magically makes it call good: scale each window
1081                 // slightly (two pixels larger in each dimension, from the
1082                 // window's center).
1083                 final float w = frame.width();
1084                 final float h = frame.height();
1085                 if (w>=1 && h>=1) {
1086                     tmpMatrix.setScale(1 + 2/w, 1 + 2/h, w/2, h/2);
1087                 } else {
1088                     tmpMatrix.reset();
1089                 }
1090             } else {
1091                 tmpMatrix.reset();
1092             }
1093             tmpMatrix.postScale(mWin.mGlobalScale, mWin.mGlobalScale);
1094             if (selfTransformation) {
1095                 tmpMatrix.postConcat(mTransformation.getMatrix());
1096             }
1097             tmpMatrix.postTranslate(frame.left + mWin.mXOffset, frame.top + mWin.mYOffset);
1098             if (attachedTransformation != null) {
1099                 tmpMatrix.postConcat(attachedTransformation.getMatrix());
1100             }
1101             if (appTransformation != null) {
1102                 tmpMatrix.postConcat(appTransformation.getMatrix());
1103             }
1104             if (screenAnimation) {
1105                 tmpMatrix.postConcat(screenRotationAnimation.getEnterTransformation().getMatrix());
1106             }
1107 
1108             //TODO (multidisplay): Magnification is supported only for the default display.
1109             if (mService.mAccessibilityController != null && displayId == Display.DEFAULT_DISPLAY) {
1110                 MagnificationSpec spec = mService.mAccessibilityController
1111                         .getMagnificationSpecForWindowLocked(mWin);
1112                 if (spec != null && !spec.isNop()) {
1113                     tmpMatrix.postScale(spec.scale, spec.scale);
1114                     tmpMatrix.postTranslate(spec.offsetX, spec.offsetY);
1115                 }
1116             }
1117 
1118             // "convert" it into SurfaceFlinger's format
1119             // (a 2x2 matrix + an offset)
1120             // Here we must not transform the position of the surface
1121             // since it is already included in the transformation.
1122             //Slog.i(TAG, "Transform: " + matrix);
1123 
1124             mHaveMatrix = true;
1125             tmpMatrix.getValues(tmpFloats);
1126             mDsDx = tmpFloats[Matrix.MSCALE_X];
1127             mDtDx = tmpFloats[Matrix.MSKEW_Y];
1128             mDsDy = tmpFloats[Matrix.MSKEW_X];
1129             mDtDy = tmpFloats[Matrix.MSCALE_Y];
1130             float x = tmpFloats[Matrix.MTRANS_X];
1131             float y = tmpFloats[Matrix.MTRANS_Y];
1132             int w = frame.width();
1133             int h = frame.height();
1134             mWin.mShownFrame.set(x, y, x+w, y+h);
1135 
1136             // Now set the alpha...  but because our current hardware
1137             // can't do alpha transformation on a non-opaque surface,
1138             // turn it off if we are running an animation that is also
1139             // transforming since it is more important to have that
1140             // animation be smooth.
1141             mShownAlpha = mAlpha;
1142             mHasClipRect = false;
1143             if (!mService.mLimitedAlphaCompositing
1144                     || (!PixelFormat.formatHasAlpha(mWin.mAttrs.format)
1145                     || (mWin.isIdentityMatrix(mDsDx, mDtDx, mDsDy, mDtDy)
1146                             && x == frame.left && y == frame.top))) {
1147                 //Slog.i(TAG, "Applying alpha transform");
1148                 if (selfTransformation) {
1149                     mShownAlpha *= mTransformation.getAlpha();
1150                 }
1151                 if (attachedTransformation != null) {
1152                     mShownAlpha *= attachedTransformation.getAlpha();
1153                 }
1154                 if (appTransformation != null) {
1155                     mShownAlpha *= appTransformation.getAlpha();
1156                     if (appTransformation.hasClipRect()) {
1157                         mClipRect.set(appTransformation.getClipRect());
1158                         if (mWin.mHScale > 0) {
1159                             mClipRect.left /= mWin.mHScale;
1160                             mClipRect.right /= mWin.mHScale;
1161                         }
1162                         if (mWin.mVScale > 0) {
1163                             mClipRect.top /= mWin.mVScale;
1164                             mClipRect.bottom /= mWin.mVScale;
1165                         }
1166                         mHasClipRect = true;
1167                     }
1168                 }
1169                 if (screenAnimation) {
1170                     mShownAlpha *= screenRotationAnimation.getEnterTransformation().getAlpha();
1171                 }
1172             } else {
1173                 //Slog.i(TAG, "Not applying alpha transform");
1174             }
1175 
1176             if ((DEBUG_SURFACE_TRACE || WindowManagerService.localLOGV)
1177                     && (mShownAlpha == 1.0 || mShownAlpha == 0.0)) Slog.v(
1178                     TAG, "computeShownFrameLocked: Animating " + this + " mAlpha=" + mAlpha
1179                     + " self=" + (selfTransformation ? mTransformation.getAlpha() : "null")
1180                     + " attached=" + (attachedTransformation == null ?
1181                             "null" : attachedTransformation.getAlpha())
1182                     + " app=" + (appTransformation == null ? "null" : appTransformation.getAlpha())
1183                     + " screen=" + (screenAnimation ?
1184                             screenRotationAnimation.getEnterTransformation().getAlpha() : "null"));
1185             return;
1186         } else if (mIsWallpaper && mService.mInnerFields.mWallpaperActionPending) {
1187             return;
1188         }
1189 
1190         if (WindowManagerService.localLOGV) Slog.v(
1191                 TAG, "computeShownFrameLocked: " + this +
1192                 " not attached, mAlpha=" + mAlpha);
1193 
1194         MagnificationSpec spec = null;
1195         //TODO (multidisplay): Magnification is supported only for the default display.
1196         if (mService.mAccessibilityController != null && displayId == Display.DEFAULT_DISPLAY) {
1197             spec = mService.mAccessibilityController.getMagnificationSpecForWindowLocked(mWin);
1198         }
1199         if (spec != null) {
1200             final Rect frame = mWin.mFrame;
1201             final float tmpFloats[] = mService.mTmpFloats;
1202             final Matrix tmpMatrix = mWin.mTmpMatrix;
1203 
1204             tmpMatrix.setScale(mWin.mGlobalScale, mWin.mGlobalScale);
1205             tmpMatrix.postTranslate(frame.left + mWin.mXOffset, frame.top + mWin.mYOffset);
1206 
1207             if (spec != null && !spec.isNop()) {
1208                 tmpMatrix.postScale(spec.scale, spec.scale);
1209                 tmpMatrix.postTranslate(spec.offsetX, spec.offsetY);
1210             }
1211 
1212             tmpMatrix.getValues(tmpFloats);
1213 
1214             mHaveMatrix = true;
1215             mDsDx = tmpFloats[Matrix.MSCALE_X];
1216             mDtDx = tmpFloats[Matrix.MSKEW_Y];
1217             mDsDy = tmpFloats[Matrix.MSKEW_X];
1218             mDtDy = tmpFloats[Matrix.MSCALE_Y];
1219             float x = tmpFloats[Matrix.MTRANS_X];
1220             float y = tmpFloats[Matrix.MTRANS_Y];
1221             int w = frame.width();
1222             int h = frame.height();
1223             mWin.mShownFrame.set(x, y, x + w, y + h);
1224 
1225             mShownAlpha = mAlpha;
1226         } else {
1227             mWin.mShownFrame.set(mWin.mFrame);
1228             if (mWin.mXOffset != 0 || mWin.mYOffset != 0) {
1229                 mWin.mShownFrame.offset(mWin.mXOffset, mWin.mYOffset);
1230             }
1231             mShownAlpha = mAlpha;
1232             mHaveMatrix = false;
1233             mDsDx = mWin.mGlobalScale;
1234             mDtDx = 0;
1235             mDsDy = 0;
1236             mDtDy = mWin.mGlobalScale;
1237         }
1238     }
1239 
applyDecorRect(final Rect decorRect)1240     private void applyDecorRect(final Rect decorRect) {
1241         final WindowState w = mWin;
1242         final int width = w.mFrame.width();
1243         final int height = w.mFrame.height();
1244 
1245         // Compute the offset of the window in relation to the decor rect.
1246         final int left = w.mXOffset + w.mFrame.left;
1247         final int top = w.mYOffset + w.mFrame.top;
1248 
1249         // Initialize the decor rect to the entire frame.
1250         w.mSystemDecorRect.set(0, 0, width, height);
1251 
1252         // Intersect with the decor rect, offsetted by window position.
1253         w.mSystemDecorRect.intersect(decorRect.left - left, decorRect.top - top,
1254                 decorRect.right - left, decorRect.bottom - top);
1255 
1256         // If size compatibility is being applied to the window, the
1257         // surface is scaled relative to the screen.  Also apply this
1258         // scaling to the crop rect.  We aren't using the standard rect
1259         // scale function because we want to round things to make the crop
1260         // always round to a larger rect to ensure we don't crop too
1261         // much and hide part of the window that should be seen.
1262         if (w.mEnforceSizeCompat && w.mInvGlobalScale != 1.0f) {
1263             final float scale = w.mInvGlobalScale;
1264             w.mSystemDecorRect.left = (int) (w.mSystemDecorRect.left * scale - 0.5f);
1265             w.mSystemDecorRect.top = (int) (w.mSystemDecorRect.top * scale - 0.5f);
1266             w.mSystemDecorRect.right = (int) ((w.mSystemDecorRect.right+1) * scale - 0.5f);
1267             w.mSystemDecorRect.bottom = (int) ((w.mSystemDecorRect.bottom+1) * scale - 0.5f);
1268         }
1269     }
1270 
updateSurfaceWindowCrop(final boolean recoveringMemory)1271     void updateSurfaceWindowCrop(final boolean recoveringMemory) {
1272         final WindowState w = mWin;
1273         final DisplayContent displayContent = w.getDisplayContent();
1274         if (displayContent == null) {
1275             return;
1276         }
1277         final DisplayInfo displayInfo = displayContent.getDisplayInfo();
1278 
1279         // Need to recompute a new system decor rect each time.
1280         if ((w.mAttrs.flags & LayoutParams.FLAG_SCALED) != 0) {
1281             // Currently can't do this cropping for scaled windows.  We'll
1282             // just keep the crop rect the same as the source surface.
1283             w.mSystemDecorRect.set(0, 0, w.mRequestedWidth, w.mRequestedHeight);
1284         } else if (!w.isDefaultDisplay()) {
1285             // On a different display there is no system decor.  Crop the window
1286             // by the screen boundaries.
1287             w.mSystemDecorRect.set(0, 0, w.mCompatFrame.width(), w.mCompatFrame.height());
1288             w.mSystemDecorRect.intersect(-w.mCompatFrame.left, -w.mCompatFrame.top,
1289                     displayInfo.logicalWidth - w.mCompatFrame.left,
1290                     displayInfo.logicalHeight - w.mCompatFrame.top);
1291         } else if (w.mLayer >= mService.mSystemDecorLayer) {
1292             // Above the decor layer is easy, just use the entire window.
1293             w.mSystemDecorRect.set(0, 0, w.mCompatFrame.width(), w.mCompatFrame.height());
1294         } else if (w.mDecorFrame.isEmpty()) {
1295             // Windows without policy decor aren't cropped.
1296             w.mSystemDecorRect.set(0, 0, w.mCompatFrame.width(), w.mCompatFrame.height());
1297         } else if (w.mAttrs.type == LayoutParams.TYPE_WALLPAPER && mAnimator.mAnimating) {
1298             // If we're animating, the wallpaper crop should only be updated at the end of the
1299             // animation.
1300             mTmpClipRect.set(w.mSystemDecorRect);
1301             applyDecorRect(w.mDecorFrame);
1302             w.mSystemDecorRect.union(mTmpClipRect);
1303         } else {
1304             // Crop to the system decor specified by policy.
1305             applyDecorRect(w.mDecorFrame);
1306         }
1307 
1308         final boolean fullscreen = w.isFullscreen(displayInfo.appWidth, displayInfo.appHeight);
1309         final Rect clipRect = mTmpClipRect;
1310         // We use the clip rect as provided by the tranformation for non-fullscreen windows to
1311         // avoid premature clipping with the system decor rect.
1312         clipRect.set((mHasClipRect && !fullscreen) ? mClipRect : w.mSystemDecorRect);
1313 
1314         // Expand the clip rect for surface insets.
1315         final WindowManager.LayoutParams attrs = w.mAttrs;
1316         clipRect.left -= attrs.surfaceInsets.left;
1317         clipRect.top -= attrs.surfaceInsets.top;
1318         clipRect.right += attrs.surfaceInsets.right;
1319         clipRect.bottom += attrs.surfaceInsets.bottom;
1320 
1321         if (mHasClipRect && fullscreen) {
1322             // We intersect the clip rect specified by the transformation with the expanded system
1323             // decor rect to prevent artifacts from drawing during animation if the transformation
1324             // clip rect extends outside the system decor rect.
1325             clipRect.intersect(mClipRect);
1326         }
1327 
1328         // The clip rect was generated assuming (0,0) as the window origin,
1329         // so we need to translate to match the actual surface coordinates.
1330         clipRect.offset(attrs.surfaceInsets.left, attrs.surfaceInsets.top);
1331 
1332         if (!clipRect.equals(mLastClipRect)) {
1333             mLastClipRect.set(clipRect);
1334             try {
1335                 if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(w,
1336                         "CROP " + clipRect.toShortString(), null);
1337                 mSurfaceControl.setWindowCrop(clipRect);
1338             } catch (RuntimeException e) {
1339                 Slog.w(TAG, "Error setting crop surface of " + w
1340                         + " crop=" + clipRect.toShortString(), e);
1341                 if (!recoveringMemory) {
1342                     mService.reclaimSomeSurfaceMemoryLocked(this, "crop", true);
1343                 }
1344             }
1345         }
1346     }
1347 
setSurfaceBoundariesLocked(final boolean recoveringMemory)1348     void setSurfaceBoundariesLocked(final boolean recoveringMemory) {
1349         final WindowState w = mWin;
1350 
1351         int width;
1352         int height;
1353         if ((w.mAttrs.flags & LayoutParams.FLAG_SCALED) != 0) {
1354             // for a scaled surface, we always want the requested
1355             // size.
1356             width  = w.mRequestedWidth;
1357             height = w.mRequestedHeight;
1358         } else {
1359             width = w.mCompatFrame.width();
1360             height = w.mCompatFrame.height();
1361         }
1362 
1363         // Something is wrong and SurfaceFlinger will not like this,
1364         // try to revert to sane values
1365         if (width < 1) {
1366             width = 1;
1367         }
1368         if (height < 1) {
1369             height = 1;
1370         }
1371 
1372         float left = w.mShownFrame.left;
1373         float top = w.mShownFrame.top;
1374 
1375         // Adjust for surface insets.
1376         final LayoutParams attrs = w.getAttrs();
1377         final int displayId = w.getDisplayId();
1378         float scale = 1.0f;
1379         // Magnification is supported only for the default display.
1380         if (mService.mAccessibilityController != null && displayId == Display.DEFAULT_DISPLAY) {
1381             MagnificationSpec spec =
1382                     mService.mAccessibilityController.getMagnificationSpecForWindowLocked(w);
1383             if (spec != null && !spec.isNop()) {
1384                 scale = spec.scale;
1385             }
1386         }
1387 
1388         width += scale * (attrs.surfaceInsets.left + attrs.surfaceInsets.right);
1389         height += scale * (attrs.surfaceInsets.top + attrs.surfaceInsets.bottom);
1390         left -= scale * attrs.surfaceInsets.left;
1391         top -= scale * attrs.surfaceInsets.top;
1392 
1393         final boolean surfaceMoved = mSurfaceX != left || mSurfaceY != top;
1394         if (surfaceMoved) {
1395             mSurfaceX = left;
1396             mSurfaceY = top;
1397 
1398             try {
1399                 if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(w,
1400                         "POS " + left + ", " + top, null);
1401                 mSurfaceControl.setPosition(left, top);
1402             } catch (RuntimeException e) {
1403                 Slog.w(TAG, "Error positioning surface of " + w
1404                         + " pos=(" + left + "," + top + ")", e);
1405                 if (!recoveringMemory) {
1406                     mService.reclaimSomeSurfaceMemoryLocked(this, "position", true);
1407                 }
1408             }
1409         }
1410 
1411         final boolean surfaceResized = mSurfaceW != width || mSurfaceH != height;
1412         if (surfaceResized) {
1413             mSurfaceW = width;
1414             mSurfaceH = height;
1415             mSurfaceResized = true;
1416 
1417             try {
1418                 if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(w,
1419                         "SIZE " + width + "x" + height, null);
1420                 mSurfaceControl.setSize(width, height);
1421                 mSurfaceControl.setMatrix(
1422                         mDsDx * w.mHScale, mDtDx * w.mVScale,
1423                         mDsDy * w.mHScale, mDtDy * w.mVScale);
1424                 mAnimator.setPendingLayoutChanges(w.getDisplayId(),
1425                         WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER);
1426                 if ((w.mAttrs.flags & LayoutParams.FLAG_DIM_BEHIND) != 0) {
1427                     final TaskStack stack = w.getStack();
1428                     if (stack != null) {
1429                         stack.startDimmingIfNeeded(this);
1430                     }
1431                 }
1432             } catch (RuntimeException e) {
1433                 // If something goes wrong with the surface (such
1434                 // as running out of memory), don't take down the
1435                 // entire system.
1436                 Slog.e(TAG, "Error resizing surface of " + w
1437                         + " size=(" + width + "x" + height + ")", e);
1438                 if (!recoveringMemory) {
1439                     mService.reclaimSomeSurfaceMemoryLocked(this, "size", true);
1440                 }
1441             }
1442         }
1443 
1444         updateSurfaceWindowCrop(recoveringMemory);
1445     }
1446 
prepareSurfaceLocked(final boolean recoveringMemory)1447     public void prepareSurfaceLocked(final boolean recoveringMemory) {
1448         final WindowState w = mWin;
1449         if (mSurfaceControl == null) {
1450             if (w.mOrientationChanging) {
1451                 if (DEBUG_ORIENTATION) {
1452                     Slog.v(TAG, "Orientation change skips hidden " + w);
1453                 }
1454                 w.mOrientationChanging = false;
1455             }
1456             return;
1457         }
1458 
1459         boolean displayed = false;
1460 
1461         computeShownFrameLocked();
1462 
1463         setSurfaceBoundariesLocked(recoveringMemory);
1464 
1465         if (mIsWallpaper && !mWin.mWallpaperVisible) {
1466             // Wallpaper is no longer visible and there is no wp target => hide it.
1467             hide();
1468         } else if (w.mAttachedHidden || !w.isOnScreen()) {
1469             hide();
1470             mService.hideWallpapersLocked(w);
1471 
1472             // If we are waiting for this window to handle an
1473             // orientation change, well, it is hidden, so
1474             // doesn't really matter.  Note that this does
1475             // introduce a potential glitch if the window
1476             // becomes unhidden before it has drawn for the
1477             // new orientation.
1478             if (w.mOrientationChanging) {
1479                 w.mOrientationChanging = false;
1480                 if (DEBUG_ORIENTATION) Slog.v(TAG,
1481                         "Orientation change skips hidden " + w);
1482             }
1483         } else if (mLastLayer != mAnimLayer
1484                 || mLastAlpha != mShownAlpha
1485                 || mLastDsDx != mDsDx
1486                 || mLastDtDx != mDtDx
1487                 || mLastDsDy != mDsDy
1488                 || mLastDtDy != mDtDy
1489                 || w.mLastHScale != w.mHScale
1490                 || w.mLastVScale != w.mVScale
1491                 || mLastHidden) {
1492             displayed = true;
1493             mLastAlpha = mShownAlpha;
1494             mLastLayer = mAnimLayer;
1495             mLastDsDx = mDsDx;
1496             mLastDtDx = mDtDx;
1497             mLastDsDy = mDsDy;
1498             mLastDtDy = mDtDy;
1499             w.mLastHScale = w.mHScale;
1500             w.mLastVScale = w.mVScale;
1501             if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(w,
1502                     "alpha=" + mShownAlpha + " layer=" + mAnimLayer
1503                     + " matrix=[" + mDsDx + "*" + w.mHScale
1504                     + "," + mDtDx + "*" + w.mVScale
1505                     + "][" + mDsDy + "*" + w.mHScale
1506                     + "," + mDtDy + "*" + w.mVScale + "]", null);
1507             if (mSurfaceControl != null) {
1508                 try {
1509                     mSurfaceAlpha = mShownAlpha;
1510                     mSurfaceControl.setAlpha(mShownAlpha);
1511                     mSurfaceLayer = mAnimLayer;
1512                     mSurfaceControl.setLayer(mAnimLayer);
1513                     mSurfaceControl.setMatrix(
1514                             mDsDx * w.mHScale, mDtDx * w.mVScale,
1515                             mDsDy * w.mHScale, mDtDy * w.mVScale);
1516 
1517                     if (mLastHidden && mDrawState == HAS_DRAWN) {
1518                         if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(w,
1519                                 "SHOW (performLayout)", null);
1520                         if (WindowManagerService.DEBUG_VISIBILITY) Slog.v(TAG, "Showing " + w
1521                                 + " during relayout");
1522                         if (showSurfaceRobustlyLocked()) {
1523                             mLastHidden = false;
1524                             if (mIsWallpaper) {
1525                                 mService.dispatchWallpaperVisibility(w, true);
1526                             }
1527                             // This draw means the difference between unique content and mirroring.
1528                             // Run another pass through performLayout to set mHasContent in the
1529                             // LogicalDisplay.
1530                             mAnimator.setPendingLayoutChanges(w.getDisplayId(),
1531                                     WindowManagerPolicy.FINISH_LAYOUT_REDO_ANIM);
1532                         } else {
1533                             w.mOrientationChanging = false;
1534                         }
1535                     }
1536                     if (mSurfaceControl != null) {
1537                         w.mToken.hasVisible = true;
1538                     }
1539                 } catch (RuntimeException e) {
1540                     Slog.w(TAG, "Error updating surface in " + w, e);
1541                     if (!recoveringMemory) {
1542                         mService.reclaimSomeSurfaceMemoryLocked(this, "update", true);
1543                     }
1544                 }
1545             }
1546         } else {
1547             if (DEBUG_ANIM && isAnimating()) {
1548                 Slog.v(TAG, "prepareSurface: No changes in animation for " + this);
1549             }
1550             displayed = true;
1551         }
1552 
1553         if (displayed) {
1554             if (w.mOrientationChanging) {
1555                 if (!w.isDrawnLw()) {
1556                     mAnimator.mBulkUpdateParams &= ~SET_ORIENTATION_CHANGE_COMPLETE;
1557                     mAnimator.mLastWindowFreezeSource = w;
1558                     if (DEBUG_ORIENTATION) Slog.v(TAG,
1559                             "Orientation continue waiting for draw in " + w);
1560                 } else {
1561                     w.mOrientationChanging = false;
1562                     if (DEBUG_ORIENTATION) Slog.v(TAG, "Orientation change complete in " + w);
1563                 }
1564             }
1565             w.mToken.hasVisible = true;
1566         }
1567     }
1568 
setTransparentRegionHintLocked(final Region region)1569     void setTransparentRegionHintLocked(final Region region) {
1570         if (mSurfaceControl == null) {
1571             Slog.w(TAG, "setTransparentRegionHint: null mSurface after mHasSurface true");
1572             return;
1573         }
1574         if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION setTransparentRegion");
1575         SurfaceControl.openTransaction();
1576         try {
1577             if (SHOW_TRANSACTIONS) WindowManagerService.logSurface(mWin,
1578                     "transparentRegionHint=" + region, null);
1579             mSurfaceControl.setTransparentRegionHint(region);
1580         } finally {
1581             SurfaceControl.closeTransaction();
1582             if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
1583                     "<<< CLOSE TRANSACTION setTransparentRegion");
1584         }
1585     }
1586 
setWallpaperOffset(RectF shownFrame)1587     void setWallpaperOffset(RectF shownFrame) {
1588         final LayoutParams attrs = mWin.getAttrs();
1589         final int left = ((int) shownFrame.left) - attrs.surfaceInsets.left;
1590         final int top = ((int) shownFrame.top) - attrs.surfaceInsets.top;
1591         if (mSurfaceX != left || mSurfaceY != top) {
1592             if (mAnimating) {
1593                 // If this window (or its app token) is animating, then the position
1594                 // of the surface will be re-computed on the next animation frame.
1595                 // We can't poke it directly here because it depends on whatever
1596                 // transformation is being applied by the animation.
1597                 return;
1598             }
1599             mSurfaceX = left;
1600             mSurfaceY = top;
1601             if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION setWallpaperOffset");
1602             SurfaceControl.openTransaction();
1603             try {
1604                 if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(mWin,
1605                         "POS " + left + ", " + top, null);
1606                 mSurfaceControl.setPosition(mWin.mFrame.left + left, mWin.mFrame.top + top);
1607                 updateSurfaceWindowCrop(false);
1608             } catch (RuntimeException e) {
1609                 Slog.w(TAG, "Error positioning surface of " + mWin
1610                         + " pos=(" + left + "," + top + ")", e);
1611             } finally {
1612                 SurfaceControl.closeTransaction();
1613                 if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG,
1614                         "<<< CLOSE TRANSACTION setWallpaperOffset");
1615             }
1616         }
1617     }
1618 
1619     /**
1620      * Try to change the pixel format without recreating the surface. This
1621      * will be common in the case of changing from PixelFormat.OPAQUE to
1622      * PixelFormat.TRANSLUCENT in the hardware-accelerated case as both
1623      * requested formats resolve to the same underlying SurfaceControl format
1624      * @return True if format was succesfully changed, false otherwise
1625      */
tryChangeFormatInPlaceLocked()1626     boolean tryChangeFormatInPlaceLocked() {
1627         if (mSurfaceControl == null) {
1628             return false;
1629         }
1630         final LayoutParams attrs = mWin.getAttrs();
1631         final boolean isHwAccelerated = (attrs.flags &
1632                 WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED) != 0;
1633         final int format = isHwAccelerated ? PixelFormat.TRANSLUCENT : attrs.format;
1634         if (format == mSurfaceFormat) {
1635             setOpaqueLocked(!PixelFormat.formatHasAlpha(attrs.format));
1636             return true;
1637         }
1638         return false;
1639     }
1640 
setOpaqueLocked(boolean isOpaque)1641     void setOpaqueLocked(boolean isOpaque) {
1642         if (mSurfaceControl == null) {
1643             return;
1644         }
1645         if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION setOpaqueLocked");
1646         SurfaceControl.openTransaction();
1647         try {
1648             if (SHOW_TRANSACTIONS) WindowManagerService.logSurface(mWin, "isOpaque=" + isOpaque,
1649                     null);
1650             mSurfaceControl.setOpaque(isOpaque);
1651         } finally {
1652             SurfaceControl.closeTransaction();
1653             if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION setOpaqueLocked");
1654         }
1655     }
1656 
setSecureLocked(boolean isSecure)1657     void setSecureLocked(boolean isSecure) {
1658         if (mSurfaceControl == null) {
1659             return;
1660         }
1661         if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION setSecureLocked");
1662         SurfaceControl.openTransaction();
1663         try {
1664             if (SHOW_TRANSACTIONS) WindowManagerService.logSurface(mWin, "isSecure=" + isSecure,
1665                     null);
1666             mSurfaceControl.setSecure(isSecure);
1667         } finally {
1668             SurfaceControl.closeTransaction();
1669             if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION setSecureLocked");
1670         }
1671     }
1672 
1673     // This must be called while inside a transaction.
performShowLocked()1674     boolean performShowLocked() {
1675         if (mWin.isHiddenFromUserLocked()) {
1676             if (DEBUG_VISIBILITY) Slog.w(TAG, "hiding " + mWin + ", belonging to " + mWin.mOwnerUid);
1677             mWin.hideLw(false);
1678             return false;
1679         }
1680         if (DEBUG_VISIBILITY || (DEBUG_STARTING_WINDOW &&
1681                 mWin.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING)) {
1682             Slog.v(TAG, "performShow on " + this
1683                     + ": mDrawState=" + drawStateToString() + " readyForDisplay="
1684                     + mWin.isReadyForDisplayIgnoringKeyguard()
1685                     + " starting=" + (mWin.mAttrs.type == TYPE_APPLICATION_STARTING)
1686                     + " during animation: policyVis=" + mWin.mPolicyVisibility
1687                     + " attHidden=" + mWin.mAttachedHidden
1688                     + " tok.hiddenRequested="
1689                     + (mWin.mAppToken != null ? mWin.mAppToken.hiddenRequested : false)
1690                     + " tok.hidden="
1691                     + (mWin.mAppToken != null ? mWin.mAppToken.hidden : false)
1692                     + " animating=" + mAnimating
1693                     + " tok animating="
1694                     + (mAppAnimator != null ? mAppAnimator.animating : false) + " Callers="
1695                     + Debug.getCallers(3));
1696         }
1697         if (mDrawState == READY_TO_SHOW && mWin.isReadyForDisplayIgnoringKeyguard()) {
1698             if (SHOW_TRANSACTIONS || DEBUG_ORIENTATION)
1699                 WindowManagerService.logSurface(mWin, "SHOW (performShowLocked)", null);
1700             if (DEBUG_VISIBILITY || (DEBUG_STARTING_WINDOW &&
1701                     mWin.mAttrs.type == WindowManager.LayoutParams.TYPE_APPLICATION_STARTING)) {
1702                 Slog.v(TAG, "Showing " + this
1703                         + " during animation: policyVis=" + mWin.mPolicyVisibility
1704                         + " attHidden=" + mWin.mAttachedHidden
1705                         + " tok.hiddenRequested="
1706                         + (mWin.mAppToken != null ? mWin.mAppToken.hiddenRequested : false)
1707                         + " tok.hidden="
1708                         + (mWin.mAppToken != null ? mWin.mAppToken.hidden : false)
1709                         + " animating=" + mAnimating
1710                         + " tok animating="
1711                         + (mAppAnimator != null ? mAppAnimator.animating : false));
1712             }
1713 
1714             mService.enableScreenIfNeededLocked();
1715 
1716             applyEnterAnimationLocked();
1717 
1718             // Force the show in the next prepareSurfaceLocked() call.
1719             mLastAlpha = -1;
1720             if (DEBUG_SURFACE_TRACE || DEBUG_ANIM)
1721                 Slog.v(TAG, "performShowLocked: mDrawState=HAS_DRAWN in " + this);
1722             mDrawState = HAS_DRAWN;
1723             mService.scheduleAnimationLocked();
1724 
1725             int i = mWin.mChildWindows.size();
1726             while (i > 0) {
1727                 i--;
1728                 WindowState c = mWin.mChildWindows.get(i);
1729                 if (c.mAttachedHidden) {
1730                     c.mAttachedHidden = false;
1731                     if (c.mWinAnimator.mSurfaceControl != null) {
1732                         c.mWinAnimator.performShowLocked();
1733                         // It hadn't been shown, which means layout not
1734                         // performed on it, so now we want to make sure to
1735                         // do a layout.  If called from within the transaction
1736                         // loop, this will cause it to restart with a new
1737                         // layout.
1738                         final DisplayContent displayContent = c.getDisplayContent();
1739                         if (displayContent != null) {
1740                             displayContent.layoutNeeded = true;
1741                         }
1742                     }
1743                 }
1744             }
1745 
1746             if (mWin.mAttrs.type != TYPE_APPLICATION_STARTING
1747                     && mWin.mAppToken != null) {
1748                 mWin.mAppToken.firstWindowDrawn = true;
1749 
1750                 if (mWin.mAppToken.startingData != null) {
1751                     if (WindowManagerService.DEBUG_STARTING_WINDOW ||
1752                             WindowManagerService.DEBUG_ANIM) Slog.v(TAG,
1753                             "Finish starting " + mWin.mToken
1754                             + ": first real window is shown, no animation");
1755                     // If this initial window is animating, stop it -- we
1756                     // will do an animation to reveal it from behind the
1757                     // starting window, so there is no need for it to also
1758                     // be doing its own stuff.
1759                     clearAnimation();
1760                     mService.mFinishedStarting.add(mWin.mAppToken);
1761                     mService.mH.sendEmptyMessage(H.FINISHED_STARTING);
1762                 }
1763                 mWin.mAppToken.updateReportedVisibilityLocked();
1764             }
1765 
1766             return true;
1767         }
1768 
1769         return false;
1770     }
1771 
1772     /**
1773      * Have the surface flinger show a surface, robustly dealing with
1774      * error conditions.  In particular, if there is not enough memory
1775      * to show the surface, then we will try to get rid of other surfaces
1776      * in order to succeed.
1777      *
1778      * @return Returns true if the surface was successfully shown.
1779      */
showSurfaceRobustlyLocked()1780     boolean showSurfaceRobustlyLocked() {
1781         try {
1782             if (mSurfaceControl != null) {
1783                 mSurfaceShown = true;
1784                 mSurfaceControl.show();
1785                 if (mWin.mTurnOnScreen) {
1786                     if (DEBUG_VISIBILITY) Slog.v(TAG,
1787                             "Show surface turning screen on: " + mWin);
1788                     mWin.mTurnOnScreen = false;
1789                     mAnimator.mBulkUpdateParams |= SET_TURN_ON_SCREEN;
1790                 }
1791             }
1792             return true;
1793         } catch (RuntimeException e) {
1794             Slog.w(TAG, "Failure showing surface " + mSurfaceControl + " in " + mWin, e);
1795         }
1796 
1797         mService.reclaimSomeSurfaceMemoryLocked(this, "show", true);
1798 
1799         return false;
1800     }
1801 
applyEnterAnimationLocked()1802     void applyEnterAnimationLocked() {
1803         final int transit;
1804         if (mEnterAnimationPending) {
1805             mEnterAnimationPending = false;
1806             transit = WindowManagerPolicy.TRANSIT_ENTER;
1807         } else {
1808             transit = WindowManagerPolicy.TRANSIT_SHOW;
1809         }
1810         applyAnimationLocked(transit, true);
1811         //TODO (multidisplay): Magnification is supported only for the default display.
1812         if (mService.mAccessibilityController != null
1813                 && mWin.getDisplayId() == Display.DEFAULT_DISPLAY) {
1814             mService.mAccessibilityController.onWindowTransitionLocked(mWin, transit);
1815         }
1816     }
1817 
1818     /**
1819      * Choose the correct animation and set it to the passed WindowState.
1820      * @param transit If AppTransition.TRANSIT_PREVIEW_DONE and the app window has been drawn
1821      *      then the animation will be app_starting_exit. Any other value loads the animation from
1822      *      the switch statement below.
1823      * @param isEntrance The animation type the last time this was called. Used to keep from
1824      *      loading the same animation twice.
1825      * @return true if an animation has been loaded.
1826      */
applyAnimationLocked(int transit, boolean isEntrance)1827     boolean applyAnimationLocked(int transit, boolean isEntrance) {
1828         if ((mLocalAnimating && mAnimationIsEntrance == isEntrance)
1829                 || mKeyguardGoingAwayAnimation) {
1830             // If we are trying to apply an animation, but already running
1831             // an animation of the same type, then just leave that one alone.
1832 
1833             // If we are in a keyguard exit animation, and the window should animate away, modify
1834             // keyguard exit animation such that it also fades out.
1835             if (mAnimation != null && mKeyguardGoingAwayAnimation
1836                     && transit == WindowManagerPolicy.TRANSIT_PREVIEW_DONE) {
1837                 applyFadeoutDuringKeyguardExitAnimation();
1838             }
1839             return true;
1840         }
1841 
1842         // Only apply an animation if the display isn't frozen.  If it is
1843         // frozen, there is no reason to animate and it can cause strange
1844         // artifacts when we unfreeze the display if some different animation
1845         // is running.
1846         if (mService.okToDisplay()) {
1847             int anim = mPolicy.selectAnimationLw(mWin, transit);
1848             int attr = -1;
1849             Animation a = null;
1850             if (anim != 0) {
1851                 a = anim != -1 ? AnimationUtils.loadAnimation(mContext, anim) : null;
1852             } else {
1853                 switch (transit) {
1854                     case WindowManagerPolicy.TRANSIT_ENTER:
1855                         attr = com.android.internal.R.styleable.WindowAnimation_windowEnterAnimation;
1856                         break;
1857                     case WindowManagerPolicy.TRANSIT_EXIT:
1858                         attr = com.android.internal.R.styleable.WindowAnimation_windowExitAnimation;
1859                         break;
1860                     case WindowManagerPolicy.TRANSIT_SHOW:
1861                         attr = com.android.internal.R.styleable.WindowAnimation_windowShowAnimation;
1862                         break;
1863                     case WindowManagerPolicy.TRANSIT_HIDE:
1864                         attr = com.android.internal.R.styleable.WindowAnimation_windowHideAnimation;
1865                         break;
1866                 }
1867                 if (attr >= 0) {
1868                     a = mService.mAppTransition.loadAnimationAttr(mWin.mAttrs, attr);
1869                 }
1870             }
1871             if (WindowManagerService.DEBUG_ANIM) Slog.v(TAG,
1872                     "applyAnimation: win=" + this
1873                     + " anim=" + anim + " attr=0x" + Integer.toHexString(attr)
1874                     + " a=" + a
1875                     + " transit=" + transit
1876                     + " isEntrance=" + isEntrance + " Callers " + Debug.getCallers(3));
1877             if (a != null) {
1878                 if (WindowManagerService.DEBUG_ANIM) {
1879                     RuntimeException e = null;
1880                     if (!WindowManagerService.HIDE_STACK_CRAWLS) {
1881                         e = new RuntimeException();
1882                         e.fillInStackTrace();
1883                     }
1884                     Slog.v(TAG, "Loaded animation " + a + " for " + this, e);
1885                 }
1886                 setAnimation(a);
1887                 mAnimationIsEntrance = isEntrance;
1888             }
1889         } else {
1890             clearAnimation();
1891         }
1892 
1893         return mAnimation != null;
1894     }
1895 
applyFadeoutDuringKeyguardExitAnimation()1896     private void applyFadeoutDuringKeyguardExitAnimation() {
1897         long startTime = mAnimation.getStartTime();
1898         long duration = mAnimation.getDuration();
1899         long elapsed = mLastAnimationTime - startTime;
1900         long fadeDuration = duration - elapsed;
1901         if (fadeDuration <= 0) {
1902             // Never mind, this would be no visible animation, so abort the animation change.
1903             return;
1904         }
1905         AnimationSet newAnimation = new AnimationSet(false /* shareInterpolator */);
1906         newAnimation.setDuration(duration);
1907         newAnimation.setStartTime(startTime);
1908         newAnimation.addAnimation(mAnimation);
1909         Animation fadeOut = AnimationUtils.loadAnimation(
1910                 mContext, com.android.internal.R.anim.app_starting_exit);
1911         fadeOut.setDuration(fadeDuration);
1912         fadeOut.setStartOffset(elapsed);
1913         newAnimation.addAnimation(fadeOut);
1914         newAnimation.initialize(mWin.mFrame.width(), mWin.mFrame.height(), mAnimDw, mAnimDh);
1915         mAnimation = newAnimation;
1916     }
1917 
dump(PrintWriter pw, String prefix, boolean dumpAll)1918     public void dump(PrintWriter pw, String prefix, boolean dumpAll) {
1919         if (mAnimating || mLocalAnimating || mAnimationIsEntrance
1920                 || mAnimation != null) {
1921             pw.print(prefix); pw.print("mAnimating="); pw.print(mAnimating);
1922                     pw.print(" mLocalAnimating="); pw.print(mLocalAnimating);
1923                     pw.print(" mAnimationIsEntrance="); pw.print(mAnimationIsEntrance);
1924                     pw.print(" mAnimation="); pw.println(mAnimation);
1925         }
1926         if (mHasTransformation || mHasLocalTransformation) {
1927             pw.print(prefix); pw.print("XForm: has=");
1928                     pw.print(mHasTransformation);
1929                     pw.print(" hasLocal="); pw.print(mHasLocalTransformation);
1930                     pw.print(" "); mTransformation.printShortString(pw);
1931                     pw.println();
1932         }
1933         if (mSurfaceControl != null) {
1934             if (dumpAll) {
1935                 pw.print(prefix); pw.print("mSurface="); pw.println(mSurfaceControl);
1936                 pw.print(prefix); pw.print("mDrawState=");
1937                 pw.print(drawStateToString());
1938                 pw.print(" mLastHidden="); pw.println(mLastHidden);
1939             }
1940             pw.print(prefix); pw.print("Surface: shown="); pw.print(mSurfaceShown);
1941                     pw.print(" layer="); pw.print(mSurfaceLayer);
1942                     pw.print(" alpha="); pw.print(mSurfaceAlpha);
1943                     pw.print(" rect=("); pw.print(mSurfaceX);
1944                     pw.print(","); pw.print(mSurfaceY);
1945                     pw.print(") "); pw.print(mSurfaceW);
1946                     pw.print(" x "); pw.println(mSurfaceH);
1947         }
1948         if (mPendingDestroySurface != null) {
1949             pw.print(prefix); pw.print("mPendingDestroySurface=");
1950                     pw.println(mPendingDestroySurface);
1951         }
1952         if (mSurfaceResized || mSurfaceDestroyDeferred) {
1953             pw.print(prefix); pw.print("mSurfaceResized="); pw.print(mSurfaceResized);
1954                     pw.print(" mSurfaceDestroyDeferred="); pw.println(mSurfaceDestroyDeferred);
1955         }
1956         if (mShownAlpha != 1 || mAlpha != 1 || mLastAlpha != 1) {
1957             pw.print(prefix); pw.print("mShownAlpha="); pw.print(mShownAlpha);
1958                     pw.print(" mAlpha="); pw.print(mAlpha);
1959                     pw.print(" mLastAlpha="); pw.println(mLastAlpha);
1960         }
1961         if (mHaveMatrix || mWin.mGlobalScale != 1) {
1962             pw.print(prefix); pw.print("mGlobalScale="); pw.print(mWin.mGlobalScale);
1963                     pw.print(" mDsDx="); pw.print(mDsDx);
1964                     pw.print(" mDtDx="); pw.print(mDtDx);
1965                     pw.print(" mDsDy="); pw.print(mDsDy);
1966                     pw.print(" mDtDy="); pw.println(mDtDy);
1967         }
1968     }
1969 
1970     @Override
toString()1971     public String toString() {
1972         StringBuffer sb = new StringBuffer("WindowStateAnimator{");
1973         sb.append(Integer.toHexString(System.identityHashCode(this)));
1974         sb.append(' ');
1975         sb.append(mWin.mAttrs.getTitle());
1976         sb.append('}');
1977         return sb.toString();
1978     }
1979 }
1980