Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 18ee31e8 authored by Dianne Hackborn's avatar Dianne Hackborn
Browse files

Fix issue #2594388: WallpaperService doesn't always call onSurfaceDestroyed()

Take care of the window manager destroying a surface, to report to the
app that it has been destroyed.  Make sure to perform a traversal when
becoming visible to re-create the surface if needed.

Change-Id: If3bc05e0106f90d4c3bad2d7575212667680fbc8
parent 2e4b98dc
Loading
Loading
Loading
Loading
+49 −29
Original line number Original line Diff line number Diff line
@@ -127,6 +127,7 @@ public abstract class WallpaperService extends Service {
        
        
        // Current window state.
        // Current window state.
        boolean mCreated;
        boolean mCreated;
        boolean mSurfaceCreated;
        boolean mIsCreating;
        boolean mIsCreating;
        boolean mDrawingAllowed;
        boolean mDrawingAllowed;
        int mWidth;
        int mWidth;
@@ -137,7 +138,6 @@ public abstract class WallpaperService extends Service {
        int mCurHeight;
        int mCurHeight;
        int mWindowFlags = WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
        int mWindowFlags = WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
        int mCurWindowFlags = mWindowFlags;
        int mCurWindowFlags = mWindowFlags;
        boolean mDestroyReportNeeded;
        final Rect mVisibleInsets = new Rect();
        final Rect mVisibleInsets = new Rect();
        final Rect mWinFrame = new Rect();
        final Rect mWinFrame = new Rect();
        final Rect mContentInsets = new Rect();
        final Rect mContentInsets = new Rect();
@@ -447,11 +447,12 @@ public abstract class WallpaperService extends Service {
            if (myHeight <= 0) myHeight = ViewGroup.LayoutParams.MATCH_PARENT;
            if (myHeight <= 0) myHeight = ViewGroup.LayoutParams.MATCH_PARENT;
            
            
            final boolean creating = !mCreated;
            final boolean creating = !mCreated;
            final boolean surfaceCreating = !mSurfaceCreated;
            final boolean formatChanged = mFormat != mSurfaceHolder.getRequestedFormat();
            final boolean formatChanged = mFormat != mSurfaceHolder.getRequestedFormat();
            boolean sizeChanged = mWidth != myWidth || mHeight != myHeight;
            boolean sizeChanged = mWidth != myWidth || mHeight != myHeight;
            final boolean typeChanged = mType != mSurfaceHolder.getRequestedType();
            final boolean typeChanged = mType != mSurfaceHolder.getRequestedType();
            final boolean flagsChanged = mCurWindowFlags != mWindowFlags;
            final boolean flagsChanged = mCurWindowFlags != mWindowFlags;
            if (forceRelayout || creating || formatChanged || sizeChanged
            if (forceRelayout || creating || surfaceCreating || formatChanged || sizeChanged
                    || typeChanged || flagsChanged) {
                    || typeChanged || flagsChanged) {


                if (DEBUG) Log.v(TAG, "Changes: creating=" + creating
                if (DEBUG) Log.v(TAG, "Changes: creating=" + creating
@@ -487,6 +488,7 @@ public abstract class WallpaperService extends Service {
                        mLayout.windowAnimations =
                        mLayout.windowAnimations =
                                com.android.internal.R.style.Animation_Wallpaper;
                                com.android.internal.R.style.Animation_Wallpaper;
                        mSession.add(mWindow, mLayout, View.VISIBLE, mContentInsets);
                        mSession.add(mWindow, mLayout, View.VISIBLE, mContentInsets);
                        mCreated = true;
                    }
                    }
                    
                    
                    mSurfaceHolder.mSurfaceLock.lock();
                    mSurfaceHolder.mSurfaceLock.lock();
@@ -513,9 +515,13 @@ public abstract class WallpaperService extends Service {
                    
                    
                    mSurfaceHolder.mSurfaceLock.unlock();
                    mSurfaceHolder.mSurfaceLock.unlock();


                    try {
                    if (!mSurfaceHolder.mSurface.isValid()) {
                        mDestroyReportNeeded = true;
                        reportSurfaceDestroyed();
                        if (DEBUG) Log.v(TAG, "Layout: Surface destroyed");
                        return;
                    }
                    
                    
                    try {
                        SurfaceHolder.Callback callbacks[] = null;
                        SurfaceHolder.Callback callbacks[] = null;
                        synchronized (mSurfaceHolder.mCallbacks) {
                        synchronized (mSurfaceHolder.mCallbacks) {
                            final int N = mSurfaceHolder.mCallbacks.size();
                            final int N = mSurfaceHolder.mCallbacks.size();
@@ -525,7 +531,7 @@ public abstract class WallpaperService extends Service {
                            }
                            }
                        }
                        }


                        if (!mCreated) {
                        if (surfaceCreating) {
                            mIsCreating = true;
                            mIsCreating = true;
                            if (DEBUG) Log.v(TAG, "onSurfaceCreated("
                            if (DEBUG) Log.v(TAG, "onSurfaceCreated("
                                    + mSurfaceHolder + "): " + this);
                                    + mSurfaceHolder + "): " + this);
@@ -536,7 +542,8 @@ public abstract class WallpaperService extends Service {
                                }
                                }
                            }
                            }
                        }
                        }
                        if (forceReport || creating || formatChanged || sizeChanged) {
                        if (forceReport || creating || surfaceCreating
                                || formatChanged || sizeChanged) {
                            if (DEBUG) {
                            if (DEBUG) {
                                RuntimeException e = new RuntimeException();
                                RuntimeException e = new RuntimeException();
                                e.fillInStackTrace();
                                e.fillInStackTrace();
@@ -559,7 +566,7 @@ public abstract class WallpaperService extends Service {
                        }
                        }
                    } finally {
                    } finally {
                        mIsCreating = false;
                        mIsCreating = false;
                        mCreated = true;
                        mSurfaceCreated = true;
                        if (creating || (relayoutResult&WindowManagerImpl.RELAYOUT_FIRST_TIME) != 0) {
                        if (creating || (relayoutResult&WindowManagerImpl.RELAYOUT_FIRST_TIME) != 0) {
                            mSession.finishDrawing(mWindow);
                            mSession.finishDrawing(mWindow);
                        }
                        }
@@ -621,6 +628,12 @@ public abstract class WallpaperService extends Service {
                    mReportedVisible = visible;
                    mReportedVisible = visible;
                    if (DEBUG) Log.v(TAG, "onVisibilityChanged(" + visible
                    if (DEBUG) Log.v(TAG, "onVisibilityChanged(" + visible
                            + "): " + this);
                            + "): " + this);
                    if (visible) {
                        // If becoming visible, in preview mode the surface
                        // may have been destroyed so now we need to make
                        // sure it is re-created.
                        updateSurface(false, false);
                    }
                    onVisibilityChanged(visible);
                    onVisibilityChanged(visible);
                }
                }
            }
            }
@@ -645,6 +658,8 @@ public abstract class WallpaperService extends Service {
                mPendingSync = false;
                mPendingSync = false;
                mOffsetMessageEnqueued = false;
                mOffsetMessageEnqueued = false;
            }
            }
            
            if (mSurfaceCreated) {
                if (DEBUG) Log.v(TAG, "Offsets change in " + this
                if (DEBUG) Log.v(TAG, "Offsets change in " + this
                        + ": " + xOffset + "," + yOffset);
                        + ": " + xOffset + "," + yOffset);
                final int availw = mIWallpaperEngine.mReqWidth-mCurWidth;
                final int availw = mIWallpaperEngine.mReqWidth-mCurWidth;
@@ -652,6 +667,7 @@ public abstract class WallpaperService extends Service {
                final int availh = mIWallpaperEngine.mReqHeight-mCurHeight;
                final int availh = mIWallpaperEngine.mReqHeight-mCurHeight;
                final int yPixels = availh > 0 ? -(int)(availh*yOffset+.5f) : 0;
                final int yPixels = availh > 0 ? -(int)(availh*yOffset+.5f) : 0;
                onOffsetsChanged(xOffset, yOffset, xOffsetStep, yOffsetStep, xPixels, yPixels);
                onOffsetsChanged(xOffset, yOffset, xOffsetStep, yOffsetStep, xPixels, yPixels);
            }
            
            
            if (sync) {
            if (sync) {
                try {
                try {
@@ -679,21 +695,9 @@ public abstract class WallpaperService extends Service {
            }
            }
        }
        }
        
        
        void detach() {
        void reportSurfaceDestroyed() {
            if (mDestroyed) {
            if (mSurfaceCreated) {
                return;
                mSurfaceCreated = false;
            }
            
            mDestroyed = true;
            
            if (mVisible) {
                mVisible = false;
                if (DEBUG) Log.v(TAG, "onVisibilityChanged(false): " + this);
                onVisibilityChanged(false);
            }
            
            if (mDestroyReportNeeded) {
                mDestroyReportNeeded = false;
                SurfaceHolder.Callback callbacks[];
                SurfaceHolder.Callback callbacks[];
                synchronized (mSurfaceHolder.mCallbacks) {
                synchronized (mSurfaceHolder.mCallbacks) {
                    callbacks = new SurfaceHolder.Callback[
                    callbacks = new SurfaceHolder.Callback[
@@ -707,6 +711,22 @@ public abstract class WallpaperService extends Service {
                        + mSurfaceHolder + "): " + this);
                        + mSurfaceHolder + "): " + this);
                onSurfaceDestroyed(mSurfaceHolder);
                onSurfaceDestroyed(mSurfaceHolder);
            }
            }
        }
        
        void detach() {
            if (mDestroyed) {
                return;
            }
            
            mDestroyed = true;
            
            if (mVisible) {
                mVisible = false;
                if (DEBUG) Log.v(TAG, "onVisibilityChanged(false): " + this);
                onVisibilityChanged(false);
            }
            
            reportSurfaceDestroyed();
            
            
            if (DEBUG) Log.v(TAG, "onDestroy(): " + this);
            if (DEBUG) Log.v(TAG, "onDestroy(): " + this);
            onDestroy();
            onDestroy();