am b54980d1: Merge "Fix issue #5588689: Black camera preview after coming back from gmail" into ics-mr1

* commit 'b54980d1d4d903f68cdfa952256afff01902cd94':
  Fix issue #5588689: Black camera preview after coming back from gmail
This commit is contained in:
Dianne Hackborn
2011-11-28 16:55:05 -08:00
committed by Android Git Automerger
10 changed files with 231 additions and 127 deletions

View File

@@ -608,7 +608,7 @@ public abstract class WallpaperService extends Service {
final int relayoutResult = mSession.relayout(
mWindow, mWindow.mSeq, mLayout, mWidth, mHeight,
View.VISIBLE, false, mWinFrame, mContentInsets,
View.VISIBLE, 0, mWinFrame, mContentInsets,
mVisibleInsets, mConfiguration, mSurfaceHolder.mSurface);
if (DEBUG) Log.v(TAG, "New surface: " + mSurfaceHolder.mSurface
@@ -654,7 +654,7 @@ public abstract class WallpaperService extends Service {
}
redrawNeeded |= creating
|| (relayoutResult&WindowManagerImpl.RELAYOUT_FIRST_TIME) != 0;
|| (relayoutResult&WindowManagerImpl.RELAYOUT_RES_FIRST_TIME) != 0;
if (forceReport || creating || surfaceCreating
|| formatChanged || sizeChanged) {

View File

@@ -54,9 +54,8 @@ interface IWindowSession {
* @param requestedWidth The width the window wants to be.
* @param requestedHeight The height the window wants to be.
* @param viewVisibility Window root view's visibility.
* @param insetsPending Set to true if the client will be later giving
* internal insets; as a result, the window will not impact other window
* layouts until the insets are given.
* @param flags Request flags: {@link WindowManagerImpl#RELAYOUT_INSETS_PENDING},
* {@link WindowManagerImpl#RELAYOUT_DEFER_SURFACE_DESTROY}.
* @param outFrame Rect in which is placed the new position/size on
* screen.
* @param outContentInsets Rect in which is placed the offsets from
@@ -80,10 +79,16 @@ interface IWindowSession {
*/
int relayout(IWindow window, int seq, in WindowManager.LayoutParams attrs,
int requestedWidth, int requestedHeight, int viewVisibility,
boolean insetsPending, out Rect outFrame, out Rect outContentInsets,
int flags, out Rect outFrame, out Rect outContentInsets,
out Rect outVisibleInsets, out Configuration outConfig,
out Surface outSurface);
/**
* If a call to relayout() asked to have the surface destroy deferred,
* it must call this once it is okay to destroy that surface.
*/
void performDeferredDestroy(IWindow window);
/**
* Called by a client to report that it ran out of graphics memory.
*/

View File

@@ -16,7 +16,6 @@
package android.view;
import android.util.DisplayMetrics;
import com.android.internal.view.BaseIWindow;
import android.content.Context;
@@ -82,7 +81,6 @@ import java.util.concurrent.locks.ReentrantLock;
public class SurfaceView extends View {
static private final String TAG = "SurfaceView";
static private final boolean DEBUG = false;
static private final boolean localLOGV = DEBUG ? true : false;
final ArrayList<SurfaceHolder.Callback> mCallbacks
= new ArrayList<SurfaceHolder.Callback>();
@@ -90,7 +88,8 @@ public class SurfaceView extends View {
final int[] mLocation = new int[2];
final ReentrantLock mSurfaceLock = new ReentrantLock();
final Surface mSurface = new Surface();
Surface mSurface = new Surface(); // Current surface in use
Surface mNewSurface = new Surface(); // New surface we are switching to
boolean mDrawingStopped = true;
final WindowManager.LayoutParams mLayout
@@ -145,8 +144,7 @@ public class SurfaceView extends View {
int mRequestedFormat = PixelFormat.RGB_565;
boolean mHaveFrame = false;
boolean mDestroyReportNeeded = false;
boolean mNewSurfaceNeeded = false;
boolean mSurfaceCreated = false;
long mLastLockTime = 0;
boolean mVisible = false;
@@ -236,46 +234,6 @@ public class SurfaceView extends View {
updateWindow(false, false);
}
/**
* This method is not intended for general use. It was created
* temporarily to improve performance of 3D layers in Launcher
* and should be removed and fixed properly.
*
* Do not call this method. Ever.
*
* @hide
*/
protected void showSurface() {
if (mSession != null) {
updateWindow(true, false);
}
}
/**
* This method is not intended for general use. It was created
* temporarily to improve performance of 3D layers in Launcher
* and should be removed and fixed properly.
*
* Do not call this method. Ever.
*
* @hide
*/
protected void hideSurface() {
if (mSession != null && mWindow != null) {
mSurfaceLock.lock();
try {
DisplayMetrics metrics = getResources().getDisplayMetrics();
mLayout.x = metrics.widthPixels * 3;
mSession.relayout(mWindow, mWindow.mSeq, mLayout, mWidth, mHeight, VISIBLE, false,
mWinFrame, mContentInsets, mVisibleInsets, mConfiguration, mSurface);
} catch (RemoteException e) {
// Ignore
} finally {
mSurfaceLock.unlock();
}
}
}
@Override
protected void onDetachedFromWindow() {
if (mGlobalListenersAdded) {
@@ -444,14 +402,13 @@ public class SurfaceView extends View {
final boolean creating = mWindow == null;
final boolean formatChanged = mFormat != mRequestedFormat;
final boolean sizeChanged = mWidth != myWidth || mHeight != myHeight;
final boolean visibleChanged = mVisible != mRequestedVisible
|| mNewSurfaceNeeded;
final boolean visibleChanged = mVisible != mRequestedVisible;
if (force || creating || formatChanged || sizeChanged || visibleChanged
|| mLeft != mLocation[0] || mTop != mLocation[1]
|| mUpdateWindowNeeded || mReportDrawNeeded || redrawNeeded) {
if (localLOGV) Log.i(TAG, "Changes: creating=" + creating
if (DEBUG) Log.i(TAG, "Changes: creating=" + creating
+ " format=" + formatChanged + " size=" + sizeChanged
+ " visible=" + visibleChanged
+ " left=" + (mLeft != mLocation[0])
@@ -496,15 +453,11 @@ public class SurfaceView extends View {
mVisible ? VISIBLE : GONE, mContentInsets);
}
if (visibleChanged && (!visible || mNewSurfaceNeeded)) {
reportSurfaceDestroyed();
}
mNewSurfaceNeeded = false;
boolean realSizeChanged;
boolean reportDrawNeeded;
int relayoutResult;
mSurfaceLock.lock();
try {
mUpdateWindowNeeded = false;
@@ -512,17 +465,21 @@ public class SurfaceView extends View {
mReportDrawNeeded = false;
mDrawingStopped = !visible;
final int relayoutResult = mSession.relayout(
if (DEBUG) Log.i(TAG, "Cur surface: " + mSurface);
relayoutResult = mSession.relayout(
mWindow, mWindow.mSeq, mLayout, mWidth, mHeight,
visible ? VISIBLE : GONE, false, mWinFrame, mContentInsets,
mVisibleInsets, mConfiguration, mSurface);
if ((relayoutResult&WindowManagerImpl.RELAYOUT_FIRST_TIME) != 0) {
visible ? VISIBLE : GONE,
WindowManagerImpl.RELAYOUT_DEFER_SURFACE_DESTROY,
mWinFrame, mContentInsets,
mVisibleInsets, mConfiguration, mNewSurface);
if ((relayoutResult&WindowManagerImpl.RELAYOUT_RES_FIRST_TIME) != 0) {
mReportDrawNeeded = true;
}
if (localLOGV) Log.i(TAG, "New surface: " + mSurface
if (DEBUG) Log.i(TAG, "New surface: " + mNewSurface
+ ", vis=" + visible + ", frame=" + mWinFrame);
mSurfaceFrame.left = 0;
mSurfaceFrame.top = 0;
if (mTranslator == null) {
@@ -547,28 +504,54 @@ public class SurfaceView extends View {
try {
redrawNeeded |= creating | reportDrawNeeded;
if (visible) {
mDestroyReportNeeded = true;
SurfaceHolder.Callback callbacks[] = null;
SurfaceHolder.Callback callbacks[];
synchronized (mCallbacks) {
callbacks = new SurfaceHolder.Callback[mCallbacks.size()];
mCallbacks.toArray(callbacks);
final boolean surfaceChanged =
(relayoutResult&WindowManagerImpl.RELAYOUT_RES_SURFACE_CHANGED) != 0;
if (mSurfaceCreated && (surfaceChanged || (!visible && visibleChanged))) {
mSurfaceCreated = false;
if (mSurface.isValid()) {
if (DEBUG) Log.i(TAG, "visibleChanged -- surfaceDestroyed");
callbacks = getSurfaceCallbacks();
for (SurfaceHolder.Callback c : callbacks) {
c.surfaceDestroyed(mSurfaceHolder);
}
}
}
if (visibleChanged) {
Surface tmpSurface = mSurface;
mSurface = mNewSurface;
mNewSurface = tmpSurface;
mNewSurface.release();
if (visible) {
if (!mSurfaceCreated && (surfaceChanged || visibleChanged)) {
mSurfaceCreated = true;
mIsCreating = true;
if (DEBUG) Log.i(TAG, "visibleChanged -- surfaceCreated");
if (callbacks == null) {
callbacks = getSurfaceCallbacks();
}
for (SurfaceHolder.Callback c : callbacks) {
c.surfaceCreated(mSurfaceHolder);
}
}
if (creating || formatChanged || sizeChanged
|| visibleChanged || realSizeChanged) {
if (DEBUG) Log.i(TAG, "surfaceChanged -- format=" + mFormat
+ " w=" + myWidth + " h=" + myHeight);
if (callbacks == null) {
callbacks = getSurfaceCallbacks();
}
for (SurfaceHolder.Callback c : callbacks) {
c.surfaceChanged(mSurfaceHolder, mFormat, myWidth, myHeight);
}
}
if (redrawNeeded) {
if (DEBUG) Log.i(TAG, "surfaceRedrawNeeded");
if (callbacks == null) {
callbacks = getSurfaceCallbacks();
}
for (SurfaceHolder.Callback c : callbacks) {
if (c instanceof SurfaceHolder.Callback2) {
((SurfaceHolder.Callback2)c).surfaceRedrawNeeded(
@@ -576,41 +559,34 @@ public class SurfaceView extends View {
}
}
}
} else {
mSurface.release();
}
} finally {
mIsCreating = false;
if (redrawNeeded) {
if (DEBUG) Log.i(TAG, "finishedDrawing");
mSession.finishDrawing(mWindow);
}
mSession.performDeferredDestroy(mWindow);
}
} catch (RemoteException ex) {
}
if (localLOGV) Log.v(
if (DEBUG) Log.v(
TAG, "Layout: x=" + mLayout.x + " y=" + mLayout.y +
" w=" + mLayout.width + " h=" + mLayout.height +
", frame=" + mSurfaceFrame);
}
}
private void reportSurfaceDestroyed() {
if (mDestroyReportNeeded) {
mDestroyReportNeeded = false;
SurfaceHolder.Callback callbacks[];
synchronized (mCallbacks) {
callbacks = new SurfaceHolder.Callback[mCallbacks.size()];
mCallbacks.toArray(callbacks);
}
for (SurfaceHolder.Callback c : callbacks) {
c.surfaceDestroyed(mSurfaceHolder);
}
private SurfaceHolder.Callback[] getSurfaceCallbacks() {
SurfaceHolder.Callback callbacks[];
synchronized (mCallbacks) {
callbacks = new SurfaceHolder.Callback[mCallbacks.size()];
mCallbacks.toArray(callbacks);
}
super.onDetachedFromWindow();
return callbacks;
}
void handleGetNewSurface() {
mNewSurfaceNeeded = true;
updateWindow(false, false);
}
@@ -636,7 +612,7 @@ public class SurfaceView extends View {
Rect visibleInsets, boolean reportDraw, Configuration newConfig) {
SurfaceView surfaceView = mSurfaceView.get();
if (surfaceView != null) {
if (localLOGV) Log.v(
if (DEBUG) Log.v(
"SurfaceView", surfaceView + " got resized: w=" +
w + " h=" + h + ", cur w=" + mCurWidth + " h=" + mCurHeight);
surfaceView.mSurfaceLock.lock();
@@ -754,7 +730,7 @@ public class SurfaceView extends View {
private final Canvas internalLockCanvas(Rect dirty) {
mSurfaceLock.lock();
if (localLOGV) Log.i(TAG, "Locking canvas... stopped="
if (DEBUG) Log.i(TAG, "Locking canvas... stopped="
+ mDrawingStopped + ", win=" + mWindow);
Canvas c = null;
@@ -774,7 +750,7 @@ public class SurfaceView extends View {
}
}
if (localLOGV) Log.i(TAG, "Returned canvas: " + c);
if (DEBUG) Log.i(TAG, "Returned canvas: " + c);
if (c != null) {
mLastLockTime = SystemClock.uptimeMillis();
return c;

View File

@@ -1426,7 +1426,7 @@ public final class ViewRootImpl extends Handler implements ViewParent,
if (!mStopped) {
boolean focusChangedDueToTouchMode = ensureTouchModeLocally(
(relayoutResult&WindowManagerImpl.RELAYOUT_IN_TOUCH_MODE) != 0);
(relayoutResult&WindowManagerImpl.RELAYOUT_RES_IN_TOUCH_MODE) != 0);
if (focusChangedDueToTouchMode || mWidth != host.getMeasuredWidth()
|| mHeight != host.getMeasuredHeight() || contentInsetsChanged) {
childWidthMeasureSpec = getRootMeasureSpec(mWidth, lp.width);
@@ -1637,7 +1637,7 @@ public final class ViewRootImpl extends Handler implements ViewParent,
mLastDrawDurationNanos = System.nanoTime() - drawStartTime;
}
if ((relayoutResult&WindowManagerImpl.RELAYOUT_FIRST_TIME) != 0
if ((relayoutResult&WindowManagerImpl.RELAYOUT_RES_FIRST_TIME) != 0
|| mReportNextDraw) {
if (LOCAL_LOGV) {
Log.v(TAG, "FINISHED DRAWING: " + mWindowAttributes.getTitle());
@@ -1670,7 +1670,7 @@ public final class ViewRootImpl extends Handler implements ViewParent,
}
// We were supposed to report when we are done drawing. Since we canceled the
// draw, remember it here.
if ((relayoutResult&WindowManagerImpl.RELAYOUT_FIRST_TIME) != 0) {
if ((relayoutResult&WindowManagerImpl.RELAYOUT_RES_FIRST_TIME) != 0) {
mReportNextDraw = true;
}
if (fullRedrawNeeded) {
@@ -3586,8 +3586,8 @@ public final class ViewRootImpl extends Handler implements ViewParent,
mWindow, mSeq, params,
(int) (mView.getMeasuredWidth() * appScale + 0.5f),
(int) (mView.getMeasuredHeight() * appScale + 0.5f),
viewVisibility, insetsPending, mWinFrame,
mPendingContentInsets, mPendingVisibleInsets,
viewVisibility, insetsPending ? WindowManagerImpl.RELAYOUT_INSETS_PENDING : 0,
mWinFrame, mPendingContentInsets, mPendingVisibleInsets,
mPendingConfiguration, mSurface);
//Log.d(TAG, "<<<<<< BACK FROM relayout");
if (restore) {
@@ -3717,7 +3717,7 @@ public final class ViewRootImpl extends Handler implements ViewParent,
// animation info.
try {
if ((relayoutWindow(mWindowAttributes, viewVisibility, false)
& WindowManagerImpl.RELAYOUT_FIRST_TIME) != 0) {
& WindowManagerImpl.RELAYOUT_RES_FIRST_TIME) != 0) {
sWindowSession.finishDrawing(mWindow);
}
} catch (RemoteException e) {

View File

@@ -63,15 +63,34 @@ public class WindowManagerImpl implements WindowManager {
* The user is navigating with keys (not the touch screen), so
* navigational focus should be shown.
*/
public static final int RELAYOUT_IN_TOUCH_MODE = 0x1;
public static final int RELAYOUT_RES_IN_TOUCH_MODE = 0x1;
/**
* This is the first time the window is being drawn,
* so the client must call drawingFinished() when done
*/
public static final int RELAYOUT_FIRST_TIME = 0x2;
public static final int RELAYOUT_RES_FIRST_TIME = 0x2;
/**
* The window manager has changed the surface from the last call.
*/
public static final int RELAYOUT_RES_SURFACE_CHANGED = 0x4;
/**
* Flag for relayout: the client will be later giving
* internal insets; as a result, the window will not impact other window
* layouts until the insets are given.
*/
public static final int RELAYOUT_INSETS_PENDING = 0x1;
/**
* Flag for relayout: the client may be currently using the current surface,
* so if it is to be destroyed as a part of the relayout the destroy must
* be deferred until later. The client will call performDeferredDestroy()
* when it is okay.
*/
public static final int RELAYOUT_DEFER_SURFACE_DESTROY = 0x2;
public static final int ADD_FLAG_APP_VISIBLE = 0x2;
public static final int ADD_FLAG_IN_TOUCH_MODE = RELAYOUT_IN_TOUCH_MODE;
public static final int ADD_FLAG_IN_TOUCH_MODE = RELAYOUT_RES_IN_TOUCH_MODE;
public static final int ADD_OKAY = 0;
public static final int ADD_BAD_APP_TOKEN = -1;

View File

@@ -18,7 +18,8 @@
*/
-->
<set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@interpolator/decelerate_quad">
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:detachWallpaper="true" android:interpolator="@interpolator/decelerate_quad">
<alpha android:fromAlpha="1.0" android:toAlpha="0.0" android:duration="160" />
</set>

View File

@@ -151,18 +151,22 @@ final class Session extends IWindowSession.Stub
public int relayout(IWindow window, int seq, WindowManager.LayoutParams attrs,
int requestedWidth, int requestedHeight, int viewFlags,
boolean insetsPending, Rect outFrame, Rect outContentInsets,
int flags, Rect outFrame, Rect outContentInsets,
Rect outVisibleInsets, Configuration outConfig, Surface outSurface) {
if (false) Slog.d(WindowManagerService.TAG, ">>>>>> ENTERED relayout from "
+ Binder.getCallingPid());
int res = mService.relayoutWindow(this, window, seq, attrs,
requestedWidth, requestedHeight, viewFlags, insetsPending,
requestedWidth, requestedHeight, viewFlags, flags,
outFrame, outContentInsets, outVisibleInsets, outConfig, outSurface);
if (false) Slog.d(WindowManagerService.TAG, "<<<<<< EXITING relayout to "
+ Binder.getCallingPid());
return res;
}
public void performDeferredDestroy(IWindow window) {
mService.performDeferredDestroyWindow(this, window);
}
public boolean outOfMemory(IWindow window) {
return mService.outOfMemoryWindow(this, window);
}

View File

@@ -2499,12 +2499,13 @@ public class WindowManagerService extends IWindowManager.Stub
public int relayoutWindow(Session session, IWindow client, int seq,
WindowManager.LayoutParams attrs, int requestedWidth,
int requestedHeight, int viewVisibility, boolean insetsPending,
int requestedHeight, int viewVisibility, int flags,
Rect outFrame, Rect outContentInsets, Rect outVisibleInsets,
Configuration outConfig, Surface outSurface) {
boolean displayed = false;
boolean inTouchMode;
boolean configChanged;
boolean surfaceChanged = false;
// if they don't have this permission, mask out the status bar bits
int systemUiVisibility = 0;
@@ -2534,6 +2535,9 @@ public class WindowManagerService extends IWindowManager.Stub
mPolicy.adjustWindowParamsLw(attrs);
}
win.mSurfaceDestroyDeferred =
(flags&WindowManagerImpl.RELAYOUT_DEFER_SURFACE_DESTROY) != 0;
int attrChanges = 0;
int flagChanges = 0;
if (attrs != null) {
@@ -2630,8 +2634,12 @@ public class WindowManagerService extends IWindowManager.Stub
// To change the format, we need to re-build the surface.
win.destroySurfaceLocked();
displayed = true;
surfaceChanged = true;
}
try {
if (win.mSurface == null) {
surfaceChanged = true;
}
Surface surface = win.createSurfaceLocked();
if (surface != null) {
outSurface.copyFrom(surface);
@@ -2683,6 +2691,7 @@ public class WindowManagerService extends IWindowManager.Stub
// If we are not currently running the exit animation, we
// need to see about starting one.
if (!win.mExiting || win.mSurfacePendingDestroy) {
surfaceChanged = true;
// Try starting an animation; if there isn't one, we
// can destroy the surface right away.
int transit = WindowManagerPolicy.TRANSIT_EXIT;
@@ -2715,10 +2724,10 @@ public class WindowManagerService extends IWindowManager.Stub
if (win.mSurface == null || (win.getAttrs().flags
& WindowManager.LayoutParams.FLAG_KEEP_SURFACE_WHILE_ANIMATING) == 0
|| win.mSurfacePendingDestroy) {
// We are being called from a local process, which
// We could be called from a local process, which
// means outSurface holds its current surface. Ensure the
// surface object is cleared, but we don't want it actually
// destroyed at this point.
// surface object is cleared, but we don't necessarily want
// it actually destroyed at this point.
win.mSurfacePendingDestroy = false;
outSurface.release();
if (DEBUG_VISIBILITY) Slog.i(TAG, "Releasing surface in: " + win);
@@ -2760,7 +2769,7 @@ public class WindowManagerService extends IWindowManager.Stub
}
mLayoutNeeded = true;
win.mGivenInsetsPending = insetsPending;
win.mGivenInsetsPending = (flags&WindowManagerImpl.RELAYOUT_INSETS_PENDING) != 0;
if (assignLayers) {
assignLayersLocked();
}
@@ -2797,8 +2806,25 @@ public class WindowManagerService extends IWindowManager.Stub
Binder.restoreCallingIdentity(origId);
return (inTouchMode ? WindowManagerImpl.RELAYOUT_IN_TOUCH_MODE : 0)
| (displayed ? WindowManagerImpl.RELAYOUT_FIRST_TIME : 0);
return (inTouchMode ? WindowManagerImpl.RELAYOUT_RES_IN_TOUCH_MODE : 0)
| (displayed ? WindowManagerImpl.RELAYOUT_RES_FIRST_TIME : 0)
| (surfaceChanged ? WindowManagerImpl.RELAYOUT_RES_SURFACE_CHANGED : 0);
}
public void performDeferredDestroyWindow(Session session, IWindow client) {
long origId = Binder.clearCallingIdentity();
try {
synchronized(mWindowMap) {
WindowState win = windowForClientLocked(session, client, false);
if (win == null) {
return;
}
win.destroyDeferredSurfaceLocked();
}
} finally {
Binder.restoreCallingIdentity(origId);
}
}
public boolean outOfMemoryWindow(Session session, IWindow client) {
@@ -3738,7 +3764,7 @@ public class WindowManagerService extends IWindowManager.Stub
return;
}
// If this is a translucent or wallpaper window, then don't
// If this is a translucent window, then don't
// show a starting window -- the current effect (a full-screen
// opaque starting window that fades away to the real contents
// when it is ready) does not work for this.
@@ -3755,7 +3781,16 @@ public class WindowManagerService extends IWindowManager.Stub
}
if (ent.array.getBoolean(
com.android.internal.R.styleable.Window_windowShowWallpaper, false)) {
return;
if (mWallpaperTarget == null) {
// If this theme is requesting a wallpaper, and the wallpaper
// is not curently visible, then this effectively serves as
// an opaque window and our starting window transition animation
// can still work. We just need to make sure the starting window
// is also showing the wallpaper.
windowFlags |= WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
} else {
return;
}
}
}
@@ -7659,7 +7694,8 @@ public class WindowManagerService extends IWindowManager.Stub
// a detached wallpaper animation.
if (nowAnimating) {
if (w.mAnimation != null) {
if (w.mAnimation.getDetachWallpaper()) {
if ((w.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0
&& w.mAnimation.getDetachWallpaper()) {
windowDetachedWallpaper = w;
}
if (w.mAnimation.getBackgroundColor() != 0) {
@@ -7679,7 +7715,8 @@ public class WindowManagerService extends IWindowManager.Stub
// displayed behind it.
if (w.mAppToken != null && w.mAppToken.animation != null
&& w.mAppToken.animating) {
if (w.mAppToken.animation.getDetachWallpaper()) {
if ((w.mAttrs.flags&FLAG_SHOW_WALLPAPER) != 0
&& w.mAppToken.animation.getDetachWallpaper()) {
windowDetachedWallpaper = w;
}
if (w.mAppToken.animation.getBackgroundColor() != 0) {

View File

@@ -85,6 +85,7 @@ final class WindowState implements WindowManagerPolicy.WindowState {
boolean mPolicyVisibilityAfterAnim = true;
boolean mAppFreezing;
Surface mSurface;
Surface mPendingDestroySurface;
boolean mReportDestroySurface;
boolean mSurfacePendingDestroy;
boolean mAttachedHidden; // is our parent window hidden?
@@ -121,7 +122,13 @@ final class WindowState implements WindowManagerPolicy.WindowState {
* we must tell them application to resize (and thus redraw itself).
*/
boolean mSurfaceResized;
/**
* Set if the client has asked that the destroy of its surface be delayed
* until it explicitly says it is okay.
*/
boolean mSurfaceDestroyDeferred;
/**
* Insets that determine the actually visible area. These are in the application's
* coordinate space (without compatibility scale applied).
@@ -764,15 +771,32 @@ final class WindowState implements WindowManagerPolicy.WindowState {
Slog.w(WindowManagerService.TAG, "Window " + this + " destroying surface "
+ mSurface + ", session " + mSession, e);
}
if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) {
RuntimeException e = null;
if (!WindowManagerService.HIDE_STACK_CRAWLS) {
e = new RuntimeException();
e.fillInStackTrace();
if (mSurfaceDestroyDeferred) {
if (mSurface != null && mPendingDestroySurface != mSurface) {
if (mPendingDestroySurface != null) {
if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) {
RuntimeException e = null;
if (!WindowManagerService.HIDE_STACK_CRAWLS) {
e = new RuntimeException();
e.fillInStackTrace();
}
WindowManagerService.logSurface(this, "DESTROY PENDING", e);
}
mPendingDestroySurface.destroy();
}
mPendingDestroySurface = mSurface;
}
WindowManagerService.logSurface(this, "DESTROY", e);
} else {
if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) {
RuntimeException e = null;
if (!WindowManagerService.HIDE_STACK_CRAWLS) {
e = new RuntimeException();
e.fillInStackTrace();
}
WindowManagerService.logSurface(this, "DESTROY", e);
}
mSurface.destroy();
}
mSurface.destroy();
} catch (RuntimeException e) {
Slog.w(WindowManagerService.TAG, "Exception thrown when destroying Window " + this
+ " surface " + mSurface + " session " + mSession
@@ -784,6 +808,28 @@ final class WindowState implements WindowManagerPolicy.WindowState {
}
}
void destroyDeferredSurfaceLocked() {
try {
if (mPendingDestroySurface != null) {
if (SHOW_TRANSACTIONS || SHOW_SURFACE_ALLOC) {
RuntimeException e = null;
if (!WindowManagerService.HIDE_STACK_CRAWLS) {
e = new RuntimeException();
e.fillInStackTrace();
}
mService.logSurface(this, "DESTROY PENDING", e);
}
mPendingDestroySurface.destroy();
}
} catch (RuntimeException e) {
Slog.w(WindowManagerService.TAG, "Exception thrown when destroying Window "
+ this + " surface " + mPendingDestroySurface
+ " session " + mSession + ": " + e.toString());
}
mSurfaceDestroyDeferred = false;
mPendingDestroySurface = null;
}
boolean finishDrawingLocked() {
if (mDrawPending) {
if (SHOW_TRANSACTIONS || WindowManagerService.DEBUG_ORIENTATION) Slog.v(
@@ -977,6 +1023,9 @@ final class WindowState implements WindowManagerPolicy.WindowState {
mAnimation.cancel();
mAnimation = null;
}
if (mService.mWindowDetachedWallpaper == this) {
mService.mWindowDetachedWallpaper = null;
}
mAnimLayer = mLayer;
if (mIsImWindow) {
mAnimLayer += mService.mInputMethodAnimLayerAdjustment;
@@ -1415,6 +1464,7 @@ final class WindowState implements WindowManagerPolicy.WindowState {
if (WindowManagerService.DEBUG_ADD_REMOVE) Slog.v(WindowManagerService.TAG, "Removing " + this + " from " + mAttachedWindow);
mAttachedWindow.mChildWindows.remove(this);
}
destroyDeferredSurfaceLocked();
destroySurfaceLocked();
mSession.windowRemovedLocked();
try {
@@ -1612,6 +1662,10 @@ final class WindowState implements WindowManagerPolicy.WindowState {
pw.print(") "); pw.print(mSurfaceW);
pw.print(" x "); pw.println(mSurfaceH);
}
if (mPendingDestroySurface != null) {
pw.print(prefix); pw.print("mPendingDestroySurface=");
pw.println(mPendingDestroySurface);
}
if (dumpAll) {
pw.print(prefix); pw.print("mToken="); pw.println(mToken);
pw.print(prefix); pw.print("mRootToken="); pw.println(mRootToken);
@@ -1640,6 +1694,10 @@ final class WindowState implements WindowManagerPolicy.WindowState {
if (!mRelayoutCalled) {
pw.print(prefix); pw.print("mRelayoutCalled="); pw.println(mRelayoutCalled);
}
if (mSurfaceResized || mSurfaceDestroyDeferred) {
pw.print(prefix); pw.print("mSurfaceResized="); pw.print(mSurfaceResized);
pw.print(" mSurfaceDestroyDeferred="); pw.println(mSurfaceDestroyDeferred);
}
if (mXOffset != 0 || mYOffset != 0) {
pw.print(prefix); pw.print("Offsets x="); pw.print(mXOffset);
pw.print(" y="); pw.println(mYOffset);

View File

@@ -79,12 +79,16 @@ public final class BridgeWindowSession implements IWindowSession {
}
public int relayout(IWindow arg0, int seq, LayoutParams arg1, int arg2, int arg3, int arg4,
boolean arg4_5, Rect arg5, Rect arg6, Rect arg7, Configuration arg7b, Surface arg8)
int arg4_5, Rect arg5, Rect arg6, Rect arg7, Configuration arg7b, Surface arg8)
throws RemoteException {
// pass for now.
return 0;
}
public void performDeferredDestroy(IWindow window) {
// pass for now.
}
public boolean outOfMemory(IWindow window) throws RemoteException {
return false;
}