diff --git a/services/java/com/android/server/wm/WindowAnimator.java b/services/java/com/android/server/wm/WindowAnimator.java index fa009eb81b7ba..00fd7d8f6eca6 100644 --- a/services/java/com/android/server/wm/WindowAnimator.java +++ b/services/java/com/android/server/wm/WindowAnimator.java @@ -23,7 +23,6 @@ import com.android.internal.policy.impl.PhoneWindowManager; import java.io.PrintWriter; import java.util.ArrayList; -import java.util.HashSet; /** * Singleton class that carries out the animations and Surface operations in a separate task @@ -36,8 +35,7 @@ public class WindowAnimator { final Context mContext; final WindowManagerPolicy mPolicy; - HashSet mWinAnimators = new HashSet(); - HashSet mFinished = new HashSet(); + ArrayList mWinAnimators = new ArrayList(); boolean mAnimating; boolean mTokenMayBeDrawn; @@ -449,16 +447,9 @@ public class WindowAnimator { mScreenRotationAnimation.updateSurfaces(); } - mFinished.clear(); - for (final WindowStateAnimator winAnimator : mWinAnimators) { - if (winAnimator.mSurface == null) { - mFinished.add(winAnimator); - } else { - winAnimator.prepareSurfaceLocked(true); - } - } - for (final WindowStateAnimator winAnimator : mFinished) { - mWinAnimators.remove(winAnimator); + final int N = mWinAnimators.size(); + for (int i = 0; i < N; i++) { + mWinAnimators.get(i).prepareSurfaceLocked(true); } if (mDimParams != null) { @@ -477,6 +468,10 @@ public class WindowAnimator { mService.mBlackFrame.clearMatrix(); } } + + if (mService.mWatermark != null) { + mService.mWatermark.drawIfNeeded(); + } } catch (RuntimeException e) { Log.wtf(TAG, "Unhandled exception in Window Manager", e); } finally { diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java index b0e017f136cea..82018fe46cfb0 100644 --- a/services/java/com/android/server/wm/WindowManagerService.java +++ b/services/java/com/android/server/wm/WindowManagerService.java @@ -175,6 +175,7 @@ public class WindowManagerService extends IWindowManager.Stub static final boolean DEBUG_SCREENSHOT = false; static final boolean DEBUG_BOOT = false; static final boolean DEBUG_LAYOUT_REPEATS = true; + static final boolean DEBUG_SURFACE_TRACE = false; static final boolean SHOW_SURFACE_ALLOC = false; static final boolean SHOW_TRANSACTIONS = false; static final boolean SHOW_LIGHT_TRANSACTIONS = false || SHOW_TRANSACTIONS; @@ -425,7 +426,7 @@ public class WindowManagerService extends IWindowManager.Stub IInputMethodManager mInputMethodManager; - SurfaceSession mFxSession; + final SurfaceSession mFxSession; Watermark mWatermark; StrictModeFlash mStrictModeFlash; @@ -862,6 +863,11 @@ public class WindowManagerService extends IWindowManager.Stub // Add ourself to the Watchdog monitors. Watchdog.getInstance().addMonitor(this); + mFxSession = new SurfaceSession(); + + Surface.openTransaction(); + createWatermark(); + Surface.closeTransaction(); } public InputManagerService getInputManagerService() { @@ -7592,7 +7598,8 @@ public class WindowManagerService extends IWindowManager.Stub if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "Check opening app" + wtoken + ": allDrawn=" + wtoken.allDrawn + " startingDisplayed=" - + wtoken.startingDisplayed); + + wtoken.startingDisplayed + " startingMoved=" + + wtoken.startingMoved); if (!wtoken.allDrawn && !wtoken.startingDisplayed && !wtoken.startingMoved) { goodToGo = false; @@ -8058,23 +8065,13 @@ public class WindowManagerService extends IWindowManager.Stub mInnerFields.mHoldScreen = null; mInnerFields.mScreenBrightness = -1; mInnerFields.mButtonBrightness = -1; - boolean focusDisplayed = false; mAnimator.mAnimating = false; - boolean createWatermark = false; - - if (mFxSession == null) { - mFxSession = new SurfaceSession(); - createWatermark = true; - } if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION performLayoutAndPlaceSurfaces"); Surface.openTransaction(); - if (createWatermark) { - createWatermark(); - } if (mWatermark != null) { mWatermark.positionSurface(dw, dh); } @@ -8145,6 +8142,7 @@ public class WindowManagerService extends IWindowManager.Stub mInnerFields.mDimming = false; mInnerFields.mSyswin = false; + boolean focusDisplayed = false; final int N = mWindows.size(); for (i=N-1; i>=0; i--) { WindowState w = mWindows.get(i); @@ -8168,6 +8166,10 @@ public class WindowManagerService extends IWindowManager.Stub updateWallpaperVisibilityLocked(); } } + if (focusDisplayed) { + mH.sendEmptyMessage(H.REPORT_LOSING_FOCUS); + } + if (!mInnerFields.mDimming && mAnimator.isDimming()) { mAnimator.stopDimming(); } @@ -8294,15 +8296,18 @@ public class WindowManagerService extends IWindowManager.Stub // Update animations of all applications, including those // associated with exiting/removed apps - mAnimator.animate(); - mPendingLayoutChanges |= mAnimator.mPendingLayoutChanges; - if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("after animate()", mPendingLayoutChanges); - - if (SHOW_LIGHT_TRANSACTIONS) Slog.i(TAG, - "<<< CLOSE TRANSACTION performLayoutAndPlaceSurfaces"); - - if (mWatermark != null) { - mWatermark.drawIfNeeded(); + synchronized (mAnimator) { + final ArrayList winAnimators = mAnimator.mWinAnimators; + winAnimators.clear(); + for (i = 0; i < N; i++) { + final WindowStateAnimator winAnimator = mWindows.get(i).mWinAnimator; + if (winAnimator.mSurface != null) { + winAnimators.add(winAnimator); + } + } + mAnimator.animate(); + mPendingLayoutChanges |= mAnimator.mPendingLayoutChanges; + if (DEBUG_LAYOUT_REPEATS) debugLayoutRepeats("after animate()", mPendingLayoutChanges); } if (DEBUG_ORIENTATION && mDisplayFrozen) Slog.v(TAG, @@ -8415,9 +8420,6 @@ public class WindowManagerService extends IWindowManager.Stub mToBottomApps.clear(); } - if (focusDisplayed) { - mH.sendEmptyMessage(H.REPORT_LOSING_FOCUS); - } if (wallpaperDestroyed) { mLayoutNeeded |= adjustWallpaperWindowsLocked() != 0; } @@ -8588,7 +8590,6 @@ public class WindowManagerService extends IWindowManager.Stub wsa.mSurfaceShown = false; wsa.mSurface = null; ws.mHasSurface = false; - mAnimator.mWinAnimators.remove(wsa); mForceRemoves.add(ws); i--; N--; @@ -8602,7 +8603,6 @@ public class WindowManagerService extends IWindowManager.Stub wsa.mSurfaceShown = false; wsa.mSurface = null; ws.mHasSurface = false; - mAnimator.mWinAnimators.remove(wsa); leakedSurface = true; } } @@ -8642,7 +8642,6 @@ public class WindowManagerService extends IWindowManager.Stub winAnimator.mSurfaceShown = false; winAnimator.mSurface = null; winAnimator.mWin.mHasSurface = false; - mAnimator.mWinAnimators.remove(winAnimator); } try { diff --git a/services/java/com/android/server/wm/WindowStateAnimator.java b/services/java/com/android/server/wm/WindowStateAnimator.java index 941a5e1b68d27..164325bbedd51 100644 --- a/services/java/com/android/server/wm/WindowStateAnimator.java +++ b/services/java/com/android/server/wm/WindowStateAnimator.java @@ -10,11 +10,14 @@ import static com.android.server.wm.WindowManagerService.LayoutFields.CLEAR_ORIE import android.content.Context; import android.graphics.Matrix; import android.graphics.PixelFormat; +import android.graphics.Point; +import android.graphics.PointF; import android.graphics.Rect; import android.graphics.Region; import android.os.RemoteException; import android.util.Slog; import android.view.Surface; +import android.view.SurfaceSession; import android.view.WindowManager; import android.view.WindowManagerPolicy; import android.view.WindowManager.LayoutParams; @@ -25,6 +28,7 @@ import android.view.animation.Transformation; import com.android.server.wm.WindowManagerService.H; import java.io.PrintWriter; +import java.util.ArrayList; /** * Keep track of animations and surface operations for a single WindowState. @@ -39,6 +43,7 @@ class WindowStateAnimator { static final boolean SHOW_SURFACE_ALLOC = WindowManagerService.SHOW_SURFACE_ALLOC; static final boolean localLOGV = WindowManagerService.localLOGV; static final boolean DEBUG_ORIENTATION = WindowManagerService.DEBUG_ORIENTATION; + static final boolean DEBUG_SURFACE_TRACE = WindowManagerService.DEBUG_SURFACE_TRACE; static final String TAG = "WindowStateAnimator"; @@ -398,6 +403,105 @@ class WindowStateAnimator { return true; } + static class MySurface extends Surface { + final static ArrayList sSurfaces = new ArrayList(); + + private float mMySurfaceAlpha = 0xff; + private int mLayer; + private PointF mPosition = new PointF(); + private Point mSize = new Point(); + private boolean mShown = false; + private String mName = "Not named"; + + public MySurface(SurfaceSession s, + int pid, int display, int w, int h, int format, int flags) throws + OutOfResourcesException { + super(s, pid, display, w, h, format, flags); + mSize = new Point(w, h); + Slog.v("SurfaceTrace", "ctor: " + this); + } + + public MySurface(SurfaceSession s, + int pid, String name, int display, int w, int h, int format, int flags) + throws OutOfResourcesException { + super(s, pid, name, display, w, h, format, flags); + mName = name; + mSize = new Point(w, h); + Slog.v("SurfaceTrace", "ctor: " + this); + } + + @Override + public void setAlpha(float alpha) { + super.setAlpha(alpha); + mMySurfaceAlpha = alpha; + Slog.v("SurfaceTrace", "setAlpha: " + this); + } + + @Override + public void setLayer(int zorder) { + super.setLayer(zorder); + mLayer = zorder; + Slog.v("SurfaceTrace", "setLayer: " + this); + + sSurfaces.remove(this); + int i; + for (i = sSurfaces.size() - 1; i >= 0; i--) { + MySurface s = sSurfaces.get(i); + if (s.mLayer < zorder) { + break; + } + } + sSurfaces.add(i + 1, this); + } + + @Override + public void setPosition(float x, float y) { + super.setPosition(x, y); + mPosition = new PointF(x, y); + } + + @Override + public void setSize(int w, int h) { + super.setSize(w, h); + mSize = new Point(w, h); + } + + @Override + public void hide() { + super.hide(); + mShown = false; + Slog.v("SurfaceTrace", "hide: " + this); + } + @Override + public void show() { + super.show(); + mShown = true; + Slog.v("SurfaceTrace", "show: " + this); + } + + @Override + public void destroy() { + super.destroy(); + Slog.v("SurfaceTrace", "destroy: " + this + ". Called by " + + WindowManagerService.getCaller()); + sSurfaces.remove(this); + } + + static void dumpAllSurfaces() { + final int N = sSurfaces.size(); + for (int i = 0; i < N; i++) { + Slog.i(TAG, "SurfaceDump: " + sSurfaces.get(i)); + } + } + + @Override + public String toString() { + return "Surface " + mName + ": shown=" + mShown + " layer=" + mLayer + + " alpha=" + mMySurfaceAlpha + " " + mPosition.x + "," + mPosition.y + + " " + mSize.x + "x" + mSize.y; + } + } + Surface createSurfaceLocked() { if (mSurface == null) { mReportDestroySurface = false; @@ -452,12 +556,18 @@ class WindowStateAnimator { if (!PixelFormat.formatHasAlpha(attrs.format)) { flags |= Surface.OPAQUE; } - mSurface = new Surface( + if (DEBUG_SURFACE_TRACE) { + mSurface = new MySurface( + mSession.mSurfaceSession, mSession.mPid, + attrs.getTitle().toString(), + 0, w, h, format, flags); + } else { + mSurface = new Surface( mSession.mSurfaceSession, mSession.mPid, attrs.getTitle().toString(), 0, w, h, format, flags); + } mWin.mHasSurface = true; - mAnimator.mWinAnimators.add(this); if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) Slog.i(TAG, " CREATE SURFACE " + mSurface + " IN SESSION " @@ -468,14 +578,12 @@ class WindowStateAnimator { + " / " + this); } catch (Surface.OutOfResourcesException e) { mWin.mHasSurface = false; - mAnimator.mWinAnimators.remove(this); Slog.w(TAG, "OutOfResourcesException creating surface"); mService.reclaimSomeSurfaceMemoryLocked(this, "create", true); mDrawState = NO_SURFACE; return null; } catch (Exception e) { mWin.mHasSurface = false; - mAnimator.mWinAnimators.remove(this); Slog.e(TAG, "Exception creating surface", e); mDrawState = NO_SURFACE; return null; @@ -593,7 +701,6 @@ class WindowStateAnimator { mSurfaceShown = false; mSurface = null; mWin.mHasSurface =false; - mAnimator.mWinAnimators.remove(this); } }