Merge "Protect against surfaceController and hasSurface getting out of sync." into nyc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
ea3aa1bc56
@@ -8984,11 +8984,10 @@ public class WindowManagerService extends IWindowManager.Stub
|
|||||||
EventLog.writeEvent(EventLogTags.WM_NO_SURFACE_MEMORY, winAnimator.mWin.toString(),
|
EventLog.writeEvent(EventLogTags.WM_NO_SURFACE_MEMORY, winAnimator.mWin.toString(),
|
||||||
winAnimator.mSession.mPid, operation);
|
winAnimator.mSession.mPid, operation);
|
||||||
|
|
||||||
long callingIdentity = Binder.clearCallingIdentity();
|
final long callingIdentity = Binder.clearCallingIdentity();
|
||||||
try {
|
try {
|
||||||
// There was some problem... first, do a sanity check of the
|
// There was some problem... first, do a sanity check of the window list to make sure
|
||||||
// window list to make sure we haven't left any dangling surfaces
|
// we haven't left any dangling surfaces around.
|
||||||
// around.
|
|
||||||
|
|
||||||
Slog.i(TAG_WM, "Out of memory for surface! Looking for leaks...");
|
Slog.i(TAG_WM, "Out of memory for surface! Looking for leaks...");
|
||||||
final int numDisplays = mDisplayContents.size();
|
final int numDisplays = mDisplayContents.size();
|
||||||
@@ -8997,28 +8996,27 @@ public class WindowManagerService extends IWindowManager.Stub
|
|||||||
final int numWindows = windows.size();
|
final int numWindows = windows.size();
|
||||||
for (int winNdx = 0; winNdx < numWindows; ++winNdx) {
|
for (int winNdx = 0; winNdx < numWindows; ++winNdx) {
|
||||||
final WindowState ws = windows.get(winNdx);
|
final WindowState ws = windows.get(winNdx);
|
||||||
WindowStateAnimator wsa = ws.mWinAnimator;
|
final WindowStateAnimator wsa = ws.mWinAnimator;
|
||||||
if (wsa.mSurfaceController != null) {
|
if (wsa.mSurfaceController == null) {
|
||||||
if (!mSessions.contains(wsa.mSession)) {
|
continue;
|
||||||
Slog.w(TAG_WM, "LEAKED SURFACE (session doesn't exist): "
|
}
|
||||||
+ ws + " surface=" + wsa.mSurfaceController
|
if (!mSessions.contains(wsa.mSession)) {
|
||||||
+ " token=" + ws.mToken
|
Slog.w(TAG_WM, "LEAKED SURFACE (session doesn't exist): "
|
||||||
+ " pid=" + ws.mSession.mPid
|
+ ws + " surface=" + wsa.mSurfaceController
|
||||||
+ " uid=" + ws.mSession.mUid);
|
+ " token=" + ws.mToken
|
||||||
wsa.destroySurface();
|
+ " pid=" + ws.mSession.mPid
|
||||||
ws.setHasSurface(false);
|
+ " uid=" + ws.mSession.mUid);
|
||||||
mForceRemoves.add(ws);
|
wsa.destroySurface();
|
||||||
leakedSurface = true;
|
mForceRemoves.add(ws);
|
||||||
} else if (ws.mAppToken != null && ws.mAppToken.clientHidden) {
|
leakedSurface = true;
|
||||||
Slog.w(TAG_WM, "LEAKED SURFACE (app token hidden): "
|
} else if (ws.mAppToken != null && ws.mAppToken.clientHidden) {
|
||||||
+ ws + " surface=" + wsa.mSurfaceController
|
Slog.w(TAG_WM, "LEAKED SURFACE (app token hidden): "
|
||||||
+ " token=" + ws.mAppToken
|
+ ws + " surface=" + wsa.mSurfaceController
|
||||||
+ " saved=" + ws.mAppToken.hasSavedSurface());
|
+ " token=" + ws.mAppToken
|
||||||
if (SHOW_TRANSACTIONS) logSurface(ws, "LEAK DESTROY", false);
|
+ " saved=" + ws.mAppToken.hasSavedSurface());
|
||||||
wsa.destroySurface();
|
if (SHOW_TRANSACTIONS) logSurface(ws, "LEAK DESTROY", false);
|
||||||
ws.setHasSurface(false);
|
wsa.destroySurface();
|
||||||
leakedSurface = true;
|
leakedSurface = true;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -9061,8 +9059,7 @@ public class WindowManagerService extends IWindowManager.Stub
|
|||||||
if (surfaceController != null) {
|
if (surfaceController != null) {
|
||||||
if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) logSurface(winAnimator.mWin,
|
if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) logSurface(winAnimator.mWin,
|
||||||
"RECOVER DESTROY", false);
|
"RECOVER DESTROY", false);
|
||||||
surfaceController.destroyInTransaction();
|
winAnimator.destroySurface();
|
||||||
winAnimator.mWin.setHasSurface(false);
|
|
||||||
scheduleRemoveStartingWindowLocked(winAnimator.mWin.mAppToken);
|
scheduleRemoveStartingWindowLocked(winAnimator.mWin.mAppToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -600,119 +600,118 @@ class WindowStateAnimator {
|
|||||||
return mSurfaceController;
|
return mSurfaceController;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mSurfaceController == null) {
|
if (mSurfaceController != null) {
|
||||||
if (DEBUG_ANIM || DEBUG_ORIENTATION) Slog.i(TAG,
|
return mSurfaceController;
|
||||||
"createSurface " + this + ": mDrawState=DRAW_PENDING");
|
|
||||||
mDrawState = DRAW_PENDING;
|
|
||||||
if (w.mAppToken != null) {
|
|
||||||
if (w.mAppToken.mAppAnimator.animation == null) {
|
|
||||||
w.mAppToken.allDrawn = false;
|
|
||||||
w.mAppToken.deferClearAllDrawn = false;
|
|
||||||
} else {
|
|
||||||
// Currently animating, persist current state of allDrawn until animation
|
|
||||||
// is complete.
|
|
||||||
w.mAppToken.deferClearAllDrawn = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mService.makeWindowFreezingScreenIfNeededLocked(w);
|
|
||||||
|
|
||||||
int flags = SurfaceControl.HIDDEN;
|
|
||||||
final WindowManager.LayoutParams attrs = w.mAttrs;
|
|
||||||
|
|
||||||
if (mService.isSecureLocked(w)) {
|
|
||||||
flags |= SurfaceControl.SECURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
mTmpSize.set(w.mFrame.left + w.mXOffset, w.mFrame.top + w.mYOffset, 0, 0);
|
|
||||||
calculateSurfaceBounds(w, attrs);
|
|
||||||
final int width = mTmpSize.width();
|
|
||||||
final int height = mTmpSize.height();
|
|
||||||
|
|
||||||
if (DEBUG_VISIBILITY) {
|
|
||||||
Slog.v(TAG, "Creating surface in session "
|
|
||||||
+ mSession.mSurfaceSession + " window " + this
|
|
||||||
+ " w=" + width + " h=" + height
|
|
||||||
+ " x=" + mTmpSize.left + " y=" + mTmpSize.top
|
|
||||||
+ " format=" + attrs.format + " flags=" + flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
// We may abort, so initialize to defaults.
|
|
||||||
mLastSystemDecorRect.set(0, 0, 0, 0);
|
|
||||||
mHasClipRect = false;
|
|
||||||
mClipRect.set(0, 0, 0, 0);
|
|
||||||
mLastClipRect.set(0, 0, 0, 0);
|
|
||||||
|
|
||||||
// Set up surface control with initial size.
|
|
||||||
try {
|
|
||||||
|
|
||||||
final boolean isHwAccelerated = (attrs.flags & FLAG_HARDWARE_ACCELERATED) != 0;
|
|
||||||
final int format = isHwAccelerated ? PixelFormat.TRANSLUCENT : attrs.format;
|
|
||||||
if (!PixelFormat.formatHasAlpha(attrs.format)
|
|
||||||
// Don't make surface with surfaceInsets opaque as they display a
|
|
||||||
// translucent shadow.
|
|
||||||
&& attrs.surfaceInsets.left == 0
|
|
||||||
&& attrs.surfaceInsets.top == 0
|
|
||||||
&& attrs.surfaceInsets.right == 0
|
|
||||||
&& attrs.surfaceInsets.bottom == 0
|
|
||||||
// Don't make surface opaque when resizing to reduce the amount of
|
|
||||||
// artifacts shown in areas the app isn't drawing content to.
|
|
||||||
&& !w.isDragResizing()) {
|
|
||||||
flags |= SurfaceControl.OPAQUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
mSurfaceController = new WindowSurfaceController(mSession.mSurfaceSession,
|
|
||||||
attrs.getTitle().toString(),
|
|
||||||
width, height, format, flags, this);
|
|
||||||
|
|
||||||
w.setHasSurface(true);
|
|
||||||
|
|
||||||
if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) {
|
|
||||||
Slog.i(TAG, " CREATE SURFACE "
|
|
||||||
+ mSurfaceController + " IN SESSION "
|
|
||||||
+ mSession.mSurfaceSession
|
|
||||||
+ ": pid=" + mSession.mPid + " format="
|
|
||||||
+ attrs.format + " flags=0x"
|
|
||||||
+ Integer.toHexString(flags)
|
|
||||||
+ " / " + this);
|
|
||||||
}
|
|
||||||
} catch (OutOfResourcesException e) {
|
|
||||||
w.setHasSurface(false);
|
|
||||||
Slog.w(TAG, "OutOfResourcesException creating surface");
|
|
||||||
mService.reclaimSomeSurfaceMemoryLocked(this, "create", true);
|
|
||||||
mDrawState = NO_SURFACE;
|
|
||||||
return null;
|
|
||||||
} catch (Exception e) {
|
|
||||||
w.setHasSurface(false);
|
|
||||||
Slog.e(TAG, "Exception creating surface", e);
|
|
||||||
mDrawState = NO_SURFACE;
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (WindowManagerService.localLOGV) {
|
|
||||||
Slog.v(TAG, "Got surface: " + mSurfaceController
|
|
||||||
+ ", set left=" + w.mFrame.left + " top=" + w.mFrame.top
|
|
||||||
+ ", animLayer=" + mAnimLayer);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (SHOW_LIGHT_TRANSACTIONS) {
|
|
||||||
Slog.i(TAG, ">>> OPEN TRANSACTION createSurfaceLocked");
|
|
||||||
WindowManagerService.logSurface(w, "CREATE pos=("
|
|
||||||
+ w.mFrame.left + "," + w.mFrame.top + ") ("
|
|
||||||
+ width + "x" + height + "), layer=" + mAnimLayer + " HIDE", false);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Start a new transaction and apply position & offset.
|
|
||||||
final int layerStack = w.getDisplayContent().getDisplay().getLayerStack();
|
|
||||||
if (SHOW_TRANSACTIONS) WindowManagerService.logSurface(w,
|
|
||||||
"POS " + mTmpSize.left + ", " + mTmpSize.top, false);
|
|
||||||
mSurfaceController.setPositionAndLayer(mTmpSize.left, mTmpSize.top, layerStack,
|
|
||||||
mAnimLayer);
|
|
||||||
mLastHidden = true;
|
|
||||||
|
|
||||||
if (WindowManagerService.localLOGV) Slog.v(
|
|
||||||
TAG, "Created surface " + this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
w.setHasSurface(false);
|
||||||
|
|
||||||
|
if (DEBUG_ANIM || DEBUG_ORIENTATION) Slog.i(TAG,
|
||||||
|
"createSurface " + this + ": mDrawState=DRAW_PENDING");
|
||||||
|
|
||||||
|
mDrawState = DRAW_PENDING;
|
||||||
|
if (w.mAppToken != null) {
|
||||||
|
if (w.mAppToken.mAppAnimator.animation == null) {
|
||||||
|
w.mAppToken.allDrawn = false;
|
||||||
|
w.mAppToken.deferClearAllDrawn = false;
|
||||||
|
} else {
|
||||||
|
// Currently animating, persist current state of allDrawn until animation
|
||||||
|
// is complete.
|
||||||
|
w.mAppToken.deferClearAllDrawn = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mService.makeWindowFreezingScreenIfNeededLocked(w);
|
||||||
|
|
||||||
|
int flags = SurfaceControl.HIDDEN;
|
||||||
|
final WindowManager.LayoutParams attrs = w.mAttrs;
|
||||||
|
|
||||||
|
if (mService.isSecureLocked(w)) {
|
||||||
|
flags |= SurfaceControl.SECURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
mTmpSize.set(w.mFrame.left + w.mXOffset, w.mFrame.top + w.mYOffset, 0, 0);
|
||||||
|
calculateSurfaceBounds(w, attrs);
|
||||||
|
final int width = mTmpSize.width();
|
||||||
|
final int height = mTmpSize.height();
|
||||||
|
|
||||||
|
if (DEBUG_VISIBILITY) {
|
||||||
|
Slog.v(TAG, "Creating surface in session "
|
||||||
|
+ mSession.mSurfaceSession + " window " + this
|
||||||
|
+ " w=" + width + " h=" + height
|
||||||
|
+ " x=" + mTmpSize.left + " y=" + mTmpSize.top
|
||||||
|
+ " format=" + attrs.format + " flags=" + flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
// We may abort, so initialize to defaults.
|
||||||
|
mLastSystemDecorRect.set(0, 0, 0, 0);
|
||||||
|
mHasClipRect = false;
|
||||||
|
mClipRect.set(0, 0, 0, 0);
|
||||||
|
mLastClipRect.set(0, 0, 0, 0);
|
||||||
|
|
||||||
|
// Set up surface control with initial size.
|
||||||
|
try {
|
||||||
|
|
||||||
|
final boolean isHwAccelerated = (attrs.flags & FLAG_HARDWARE_ACCELERATED) != 0;
|
||||||
|
final int format = isHwAccelerated ? PixelFormat.TRANSLUCENT : attrs.format;
|
||||||
|
if (!PixelFormat.formatHasAlpha(attrs.format)
|
||||||
|
// Don't make surface with surfaceInsets opaque as they display a
|
||||||
|
// translucent shadow.
|
||||||
|
&& attrs.surfaceInsets.left == 0
|
||||||
|
&& attrs.surfaceInsets.top == 0
|
||||||
|
&& attrs.surfaceInsets.right == 0
|
||||||
|
&& attrs.surfaceInsets.bottom == 0
|
||||||
|
// Don't make surface opaque when resizing to reduce the amount of
|
||||||
|
// artifacts shown in areas the app isn't drawing content to.
|
||||||
|
&& !w.isDragResizing()) {
|
||||||
|
flags |= SurfaceControl.OPAQUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
mSurfaceController = new WindowSurfaceController(mSession.mSurfaceSession,
|
||||||
|
attrs.getTitle().toString(),
|
||||||
|
width, height, format, flags, this);
|
||||||
|
|
||||||
|
w.setHasSurface(true);
|
||||||
|
|
||||||
|
if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) {
|
||||||
|
Slog.i(TAG, " CREATE SURFACE "
|
||||||
|
+ mSurfaceController + " IN SESSION "
|
||||||
|
+ mSession.mSurfaceSession
|
||||||
|
+ ": pid=" + mSession.mPid + " format="
|
||||||
|
+ attrs.format + " flags=0x"
|
||||||
|
+ Integer.toHexString(flags)
|
||||||
|
+ " / " + this);
|
||||||
|
}
|
||||||
|
} catch (OutOfResourcesException e) {
|
||||||
|
Slog.w(TAG, "OutOfResourcesException creating surface");
|
||||||
|
mService.reclaimSomeSurfaceMemoryLocked(this, "create", true);
|
||||||
|
mDrawState = NO_SURFACE;
|
||||||
|
return null;
|
||||||
|
} catch (Exception e) {
|
||||||
|
Slog.e(TAG, "Exception creating surface", e);
|
||||||
|
mDrawState = NO_SURFACE;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (WindowManagerService.localLOGV) Slog.v(TAG, "Got surface: " + mSurfaceController
|
||||||
|
+ ", set left=" + w.mFrame.left + " top=" + w.mFrame.top
|
||||||
|
+ ", animLayer=" + mAnimLayer);
|
||||||
|
|
||||||
|
if (SHOW_LIGHT_TRANSACTIONS) {
|
||||||
|
Slog.i(TAG, ">>> OPEN TRANSACTION createSurfaceLocked");
|
||||||
|
WindowManagerService.logSurface(w, "CREATE pos=("
|
||||||
|
+ w.mFrame.left + "," + w.mFrame.top + ") ("
|
||||||
|
+ width + "x" + height + "), layer=" + mAnimLayer + " HIDE", false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start a new transaction and apply position & offset.
|
||||||
|
final int layerStack = w.getDisplayContent().getDisplay().getLayerStack();
|
||||||
|
if (SHOW_TRANSACTIONS) WindowManagerService.logSurface(w,
|
||||||
|
"POS " + mTmpSize.left + ", " + mTmpSize.top, false);
|
||||||
|
mSurfaceController.setPositionAndLayer(mTmpSize.left, mTmpSize.top, layerStack, mAnimLayer);
|
||||||
|
mLastHidden = true;
|
||||||
|
|
||||||
|
if (WindowManagerService.localLOGV) Slog.v(TAG, "Created surface " + this);
|
||||||
return mSurfaceController;
|
return mSurfaceController;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -783,59 +782,59 @@ class WindowStateAnimator {
|
|||||||
|
|
||||||
mWin.mSurfaceSaved = false;
|
mWin.mSurfaceSaved = false;
|
||||||
|
|
||||||
if (mSurfaceController != null) {
|
if (mSurfaceController == null) {
|
||||||
int i = mWin.mChildWindows.size();
|
return;
|
||||||
// When destroying a surface we want to make sure child windows
|
|
||||||
// are hidden. If we are preserving the surface until redraw though
|
|
||||||
// we intend to swap it out with another surface for resizing. In this case
|
|
||||||
// the window always remains visible to the user and the child windows
|
|
||||||
// should likewise remain visable.
|
|
||||||
while (!mDestroyPreservedSurfaceUponRedraw && i > 0) {
|
|
||||||
i--;
|
|
||||||
WindowState c = mWin.mChildWindows.get(i);
|
|
||||||
c.mAttachedHidden = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
if (DEBUG_VISIBILITY) logWithStack(TAG, "Window " + this + " destroying surface "
|
|
||||||
+ mSurfaceController + ", session " + mSession);
|
|
||||||
if (mSurfaceDestroyDeferred) {
|
|
||||||
if (mSurfaceController != null && mPendingDestroySurface != mSurfaceController) {
|
|
||||||
if (mPendingDestroySurface != null) {
|
|
||||||
if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) {
|
|
||||||
WindowManagerService.logSurface(mWin, "DESTROY PENDING", true);
|
|
||||||
}
|
|
||||||
mPendingDestroySurface.destroyInTransaction();
|
|
||||||
}
|
|
||||||
mPendingDestroySurface = mSurfaceController;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) {
|
|
||||||
WindowManagerService.logSurface(mWin, "DESTROY", true);
|
|
||||||
}
|
|
||||||
destroySurface();
|
|
||||||
}
|
|
||||||
// Don't hide wallpaper if we're deferring the surface destroy
|
|
||||||
// because of a surface change.
|
|
||||||
if (!mDestroyPreservedSurfaceUponRedraw) {
|
|
||||||
mWallpaperControllerLocked.hideWallpapers(mWin);
|
|
||||||
}
|
|
||||||
} catch (RuntimeException e) {
|
|
||||||
Slog.w(TAG, "Exception thrown when destroying Window " + this
|
|
||||||
+ " surface " + mSurfaceController + " session " + mSession
|
|
||||||
+ ": " + e.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Whether the surface was preserved (and copied to mPendingDestroySurface) or not, it
|
|
||||||
// needs to be cleared to match the WindowState.mHasSurface state. It is also necessary
|
|
||||||
// so it can be recreated successfully in mPendingDestroySurface case.
|
|
||||||
mWin.setHasSurface(false);
|
|
||||||
if (mSurfaceController != null) {
|
|
||||||
mSurfaceController.setShown(false);
|
|
||||||
}
|
|
||||||
mSurfaceController = null;
|
|
||||||
mDrawState = NO_SURFACE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int i = mWin.mChildWindows.size();
|
||||||
|
// When destroying a surface we want to make sure child windows are hidden. If we are
|
||||||
|
// preserving the surface until redraw though we intend to swap it out with another surface
|
||||||
|
// for resizing. In this case the window always remains visible to the user and the child
|
||||||
|
// windows should likewise remain visible.
|
||||||
|
while (!mDestroyPreservedSurfaceUponRedraw && i > 0) {
|
||||||
|
i--;
|
||||||
|
WindowState c = mWin.mChildWindows.get(i);
|
||||||
|
c.mAttachedHidden = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (DEBUG_VISIBILITY) logWithStack(TAG, "Window " + this + " destroying surface "
|
||||||
|
+ mSurfaceController + ", session " + mSession);
|
||||||
|
if (mSurfaceDestroyDeferred) {
|
||||||
|
if (mSurfaceController != null && mPendingDestroySurface != mSurfaceController) {
|
||||||
|
if (mPendingDestroySurface != null) {
|
||||||
|
if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) {
|
||||||
|
WindowManagerService.logSurface(mWin, "DESTROY PENDING", true);
|
||||||
|
}
|
||||||
|
mPendingDestroySurface.destroyInTransaction();
|
||||||
|
}
|
||||||
|
mPendingDestroySurface = mSurfaceController;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) {
|
||||||
|
WindowManagerService.logSurface(mWin, "DESTROY", true);
|
||||||
|
}
|
||||||
|
destroySurface();
|
||||||
|
}
|
||||||
|
// Don't hide wallpaper if we're deferring the surface destroy
|
||||||
|
// because of a surface change.
|
||||||
|
if (!mDestroyPreservedSurfaceUponRedraw) {
|
||||||
|
mWallpaperControllerLocked.hideWallpapers(mWin);
|
||||||
|
}
|
||||||
|
} catch (RuntimeException e) {
|
||||||
|
Slog.w(TAG, "Exception thrown when destroying Window " + this
|
||||||
|
+ " surface " + mSurfaceController + " session " + mSession + ": " + e.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Whether the surface was preserved (and copied to mPendingDestroySurface) or not, it
|
||||||
|
// needs to be cleared to match the WindowState.mHasSurface state. It is also necessary
|
||||||
|
// so it can be recreated successfully in mPendingDestroySurface case.
|
||||||
|
mWin.setHasSurface(false);
|
||||||
|
if (mSurfaceController != null) {
|
||||||
|
mSurfaceController.setShown(false);
|
||||||
|
}
|
||||||
|
mSurfaceController = null;
|
||||||
|
mDrawState = NO_SURFACE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void destroyDeferredSurfaceLocked() {
|
void destroyDeferredSurfaceLocked() {
|
||||||
@@ -1746,8 +1745,18 @@ class WindowStateAnimator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void destroySurface() {
|
void destroySurface() {
|
||||||
mSurfaceController.destroyInTransaction();
|
try {
|
||||||
mSurfaceController = null;
|
if (mSurfaceController != null) {
|
||||||
|
mSurfaceController.destroyInTransaction();
|
||||||
|
}
|
||||||
|
} catch (RuntimeException e) {
|
||||||
|
Slog.w(TAG, "Exception thrown when destroying surface " + this
|
||||||
|
+ " surface " + mSurfaceController + " session " + mSession + ": " + e);
|
||||||
|
} finally {
|
||||||
|
mWin.setHasSurface(false);
|
||||||
|
mSurfaceController = null;
|
||||||
|
mDrawState = NO_SURFACE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void setMoveAnimation(int left, int top) {
|
void setMoveAnimation(int left, int top) {
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package com.android.server.wm;
|
package com.android.server.wm;
|
||||||
|
|
||||||
|
import static com.android.server.wm.WindowManagerDebugConfig.SHOW_SURFACE_ALLOC;
|
||||||
import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS;
|
import static com.android.server.wm.WindowManagerDebugConfig.SHOW_TRANSACTIONS;
|
||||||
import static com.android.server.wm.WindowManagerDebugConfig.SHOW_LIGHT_TRANSACTIONS;
|
import static com.android.server.wm.WindowManagerDebugConfig.SHOW_LIGHT_TRANSACTIONS;
|
||||||
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_SURFACE_TRACE;
|
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_SURFACE_TRACE;
|
||||||
@@ -133,11 +134,14 @@ class WindowSurfaceController {
|
|||||||
Slog.i(TAG, "Destroying surface " + this + " called by " + Debug.getCallers(4));
|
Slog.i(TAG, "Destroying surface " + this + " called by " + Debug.getCallers(4));
|
||||||
// }
|
// }
|
||||||
try {
|
try {
|
||||||
mSurfaceControl.destroy();
|
if (mSurfaceControl != null) {
|
||||||
mSurfaceShown = false;
|
mSurfaceControl.destroy();
|
||||||
mSurfaceControl = null;
|
}
|
||||||
} catch (RuntimeException e) {
|
} catch (RuntimeException e) {
|
||||||
Slog.w(TAG, "Error destroying surface in: " + this, e);
|
Slog.w(TAG, "Error destroying surface in: " + this, e);
|
||||||
|
} finally {
|
||||||
|
mSurfaceShown = false;
|
||||||
|
mSurfaceControl = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user