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

Commit 0586a1b7 authored by Dianne Hackborn's avatar Dianne Hackborn
Browse files

Fix issue #2095422: Some fades from opaque to transparent don't work

ViewRoot was using Surface.clear(), which has different behavior
in different processes -- in the system process it would kill the
surface, causing all windows in that process to immediately disappear
instead of animating away.

This change makes Surface.release() public and uses that instead.  It
also renames Surface.clear() to Surface.destroy().

Also fixed some issues in the window manager that were causing the
wallpaper to not get immediately resized when the orientation changes
and its target window is removed and re-added.

Change-Id: I2a992e365cf5747511f0bf1193db32dc2525b218
parent 88e62579
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -377,6 +377,7 @@ public abstract class WallpaperService extends Service {
                    if (!mCreated) {
                        mLayout.type = mIWallpaperEngine.mWindowType;
                        mLayout.gravity = Gravity.LEFT|Gravity.TOP;
                        mLayout.setTitle(WallpaperService.this.getClass().getName());
                        mLayout.windowAnimations =
                                com.android.internal.R.style.Animation_Wallpaper;
                        mSession.add(mWindow, mLayout, View.VISIBLE, mContentInsets);
@@ -558,7 +559,7 @@ public abstract class WallpaperService extends Service {
                    mSession.remove(mWindow);
                } catch (RemoteException e) {
                }
                mSurfaceHolder.mSurface.clear();
                mSurfaceHolder.mSurface.release();
                mCreated = false;
            }
        }
+7 −5
Original line number Diff line number Diff line
@@ -181,7 +181,7 @@ public class Surface implements Parcelable {
    public Surface(SurfaceSession s,
            int pid, int display, int w, int h, int format, int flags)
        throws OutOfResourcesException {
        mCanvas = new Canvas();
        mCanvas = new CompatibleCanvas();
        init(s,pid,display,w,h,format,flags);
    }

@@ -271,8 +271,12 @@ public class Surface implements Parcelable {
     */
    public native   boolean isValid();
    
    /** Call this free the surface up. {@hide} */
    public native   void clear();
    /** Free all server-side state associated with this surface and
     * release this object's reference. {@hide} */
    public native void destroy();
    
    /** Release the local reference to the server-side surface. @hide */
    public native void release();
    
    /** draw into a surface */
    public Canvas lockCanvas(Rect dirty) throws OutOfResourcesException, IllegalArgumentException
@@ -400,6 +404,4 @@ public class Surface implements Parcelable {
            throws OutOfResourcesException;

    private native void init(Parcel source);
    
    private native void release();
}
+2 −2
Original line number Diff line number Diff line
@@ -1575,7 +1575,7 @@ public final class ViewRoot extends Handler implements ViewParent,
        if (mUseGL) {
            destroyGL();
        }
        mSurface.clear();
        mSurface.release();

        try {
            sWindowSession.remove(mWindow);
@@ -2532,7 +2532,7 @@ public final class ViewRoot extends Handler implements ViewParent,
                    }
                }

                mSurface.clear();
                mSurface.release();
            }
            if (mAdded) {
                mAdded = false;
+2 −2
Original line number Diff line number Diff line
@@ -214,7 +214,7 @@ static void Surface_initParcel(JNIEnv* env, jobject clazz, jobject argParcel)
    setSurface(env, clazz, rhs);
}

static void Surface_clear(JNIEnv* env, jobject clazz, uintptr_t *ostack)
static void Surface_destroy(JNIEnv* env, jobject clazz, uintptr_t *ostack)
{
    const sp<SurfaceControl>& surface(getSurfaceControl(env, clazz));
    if (SurfaceControl::isValid(surface)) {
@@ -622,7 +622,7 @@ static JNINativeMethod gSurfaceMethods[] = {
    {"nativeClassInit",     "()V",  (void*)nativeClassInit },
    {"init",                "(Landroid/view/SurfaceSession;IIIIII)V",  (void*)Surface_init },
    {"init",                "(Landroid/os/Parcel;)V",  (void*)Surface_initParcel },
    {"clear",               "()V",  (void*)Surface_clear },
    {"destroy",             "()V",  (void*)Surface_destroy },
    {"release",             "()V",  (void*)Surface_release },
	{"copyFrom",            "(Landroid/view/Surface;)V",  (void*)Surface_copyFrom },
	{"isValid",             "()Z",  (void*)Surface_isValid },
+117 −28
Original line number Diff line number Diff line
@@ -1207,8 +1207,11 @@ public class WindowManagerService extends IWindowManager.Stub
                || mLowerWallpaperTarget != null;
    }
    
    boolean adjustWallpaperWindowsLocked() {
        boolean changed = false;
    static final int ADJUST_WALLPAPER_LAYERS_CHANGED = 1<<1;
    static final int ADJUST_WALLPAPER_VISIBILITY_CHANGED = 1<<2;
    
    int adjustWallpaperWindowsLocked() {
        int changed = 0;
        
        final int dw = mDisplay.getWidth();
        final int dh = mDisplay.getHeight();
@@ -1274,12 +1277,12 @@ public class WindowManagerService extends IWindowManager.Stub
            if (mWallpaperTarget != null && mWallpaperTarget.mAppToken != null) {
                if (DEBUG_WALLPAPER) Log.v(TAG,
                        "Wallpaper not changing: waiting for app anim in current target");
                return false;
                return 0;
            }
            if (foundW != null && foundW.mAppToken != null) {
                if (DEBUG_WALLPAPER) Log.v(TAG,
                        "Wallpaper not changing: waiting for app anim in found target");
                return false;
                return 0;
            }
        }
        
@@ -1410,7 +1413,13 @@ public class WindowManagerService extends IWindowManager.Stub
        while (curTokenIndex > 0) {
            curTokenIndex--;
            WindowToken token = mWallpaperTokens.get(curTokenIndex);
            if (token.hidden == visible) {
                changed |= ADJUST_WALLPAPER_VISIBILITY_CHANGED;
                token.hidden = !visible;
                // Need to do a layout to ensure the wallpaper now has the
                // correct size.
                mLayoutNeeded = true;
            }
            
            int curWallpaperIndex = token.windows.size();
            while (curWallpaperIndex > 0) {
@@ -1463,7 +1472,7 @@ public class WindowManagerService extends IWindowManager.Stub
                        + " from " + oldIndex + " to " + foundI);
                
                localmWindows.add(foundI, wallpaper);
                changed = true;
                changed |= ADJUST_WALLPAPER_LAYERS_CHANGED;
            }
        }
        
@@ -1574,7 +1583,12 @@ public class WindowManagerService extends IWindowManager.Stub
        while (curTokenIndex > 0) {
            curTokenIndex--;
            WindowToken token = mWallpaperTokens.get(curTokenIndex);
            if (token.hidden == visible) {
                token.hidden = !visible;
                // Need to do a layout to ensure the wallpaper now has the
                // correct size.
                mLayoutNeeded = true;
            }
            
            int curWallpaperIndex = token.windows.size();
            while (curWallpaperIndex > 0) {
@@ -1999,10 +2013,15 @@ public class WindowManagerService extends IWindowManager.Stub
            synchronized (mWindowMap) {
                WindowState w = windowForClientLocked(session, client);
                if ((w != null) && (w.mSurface != null)) {
                    if (SHOW_TRANSACTIONS) Log.i(TAG, ">>> OPEN TRANSACTION");
                    Surface.openTransaction();
                    try {
                        if (SHOW_TRANSACTIONS) Log.i(
                                TAG, "  SURFACE " + w.mSurface
                                + ": transparentRegionHint=" + region);
                        w.mSurface.setTransparentRegionHint(region);
                    } finally {
                        if (SHOW_TRANSACTIONS) Log.i(TAG, "<<< CLOSE TRANSACTION");
                        Surface.closeTransaction();
                    }
                }
@@ -2149,8 +2168,12 @@ public class WindowManagerService extends IWindowManager.Stub
                    Surface surface = win.createSurfaceLocked();
                    if (surface != null) {
                        outSurface.copyFrom(surface);
                        if (SHOW_TRANSACTIONS) Log.i(TAG,
                                "  OUT SURFACE " + outSurface + ": copied");
                    } else {
                        outSurface.clear();
                        // For some reason there isn't a surface.  Clear the
                        // caller's object so they see the same state.
                        outSurface.release();
                    }
                } catch (Exception e) {
                    Log.w(TAG, "Exception thrown when creating surface for client "
@@ -2196,7 +2219,11 @@ public class WindowManagerService extends IWindowManager.Stub
                        }
                    }
                }
                outSurface.clear();
                // We are being 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.
                outSurface.release();
            }

            if (focusMayChange) {
@@ -2217,7 +2244,7 @@ public class WindowManagerService extends IWindowManager.Stub
                }
            }
            if (wallpaperMayMove) {
                if (adjustWallpaperWindowsLocked()) {
                if ((adjustWallpaperWindowsLocked()&ADJUST_WALLPAPER_LAYERS_CHANGED) != 0) {
                    assignLayers = true;
                }
            }
@@ -6281,6 +6308,8 @@ public class WindowManagerService extends IWindowManager.Stub
                if (localLOGV) Log.v(
                    TAG, "First window added to " + this + ", creating SurfaceSession");
                mSurfaceSession = new SurfaceSession();
                if (SHOW_TRANSACTIONS) Log.i(
                        TAG, "  NEW SURFACE SESSION " + mSurfaceSession);
                mSessions.add(this);
            }
            mNumWindow++;
@@ -6298,6 +6327,8 @@ public class WindowManagerService extends IWindowManager.Stub
                    if (localLOGV) Log.v(
                        TAG, "Last window removed from " + this
                        + ", destroying " + mSurfaceSession);
                    if (SHOW_TRANSACTIONS) Log.i(
                            TAG, "  KILL SURFACE SESSION " + mSurfaceSession);
                    try {
                        mSurfaceSession.kill();
                    } catch (Exception e) {
@@ -6794,6 +6825,12 @@ public class WindowManagerService extends IWindowManager.Stub
                    mSurface = new Surface(
                            mSession.mSurfaceSession, mSession.mPid,
                            0, w, h, mAttrs.format, flags);
                    if (SHOW_TRANSACTIONS) Log.i(TAG, "  CREATE SURFACE "
                            + mSurface + " IN SESSION "
                            + mSession.mSurfaceSession
                            + ": pid=" + mSession.mPid + " format="
                            + mAttrs.format + " flags=0x"
                            + Integer.toHexString(flags));
                } catch (Surface.OutOfResourcesException e) {
                    Log.w(TAG, "OutOfResourcesException creating surface");
                    reclaimSomeSurfaceMemoryLocked(this, "create");
@@ -6823,6 +6860,8 @@ public class WindowManagerService extends IWindowManager.Stub
                        mSurface.setLayer(mAnimLayer);
                        mSurface.hide();
                        if ((mAttrs.flags&WindowManager.LayoutParams.FLAG_DITHER) != 0) {
                            if (SHOW_TRANSACTIONS) Log.i(TAG, "  SURFACE "
                                    + mSurface + ": DITHER");
                            mSurface.setFlags(Surface.SURFACE_DITHER,
                                    Surface.SURFACE_DITHER);
                        }
@@ -6868,7 +6907,7 @@ public class WindowManagerService extends IWindowManager.Stub
                        Log.i(TAG, "  SURFACE " + mSurface + ": DESTROY ("
                                + mAttrs.getTitle() + ")", ex);
                    }
                    mSurface.clear();
                    mSurface.destroy();
                } catch (RuntimeException e) {
                    Log.w(TAG, "Exception thrown when destroying Window " + this
                        + " surface " + mSurface + " session " + mSession
@@ -8840,6 +8879,8 @@ public class WindowManagerService extends IWindowManager.Stub
                        if (w.commitFinishDrawingLocked(currentTime)) {
                            if ((w.mAttrs.flags
                                    & WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER) != 0) {
                                if (DEBUG_WALLPAPER) Log.v(TAG,
                                        "First draw done in potential wallpaper target " + w);
                                wallpaperMayChange = true;
                            }
                        }
@@ -9134,10 +9175,23 @@ public class WindowManagerService extends IWindowManager.Stub
                }
                
                if (wallpaperMayChange) {
                    if (adjustWallpaperWindowsLocked()) {
                    if (DEBUG_WALLPAPER) Log.v(TAG,
                            "Wallpaper may change!  Adjusting");
                    int adjResult = adjustWallpaperWindowsLocked();
                    if ((adjResult&ADJUST_WALLPAPER_LAYERS_CHANGED) != 0) {
                        if (DEBUG_WALLPAPER) Log.v(TAG,
                                "Wallpaper layer changed: assigning layers + relayout");
                        restart = true;
                        mLayoutNeeded = true;
                        assignLayersLocked();
                    } else if ((adjResult&ADJUST_WALLPAPER_VISIBILITY_CHANGED) != 0) {
                        if (DEBUG_WALLPAPER) Log.v(TAG,
                                "Wallpaper visibility changed: relayout");
                        restart = true;
                        mLayoutNeeded = true;
                    }
                    if (mLayoutNeeded) {
                        restart = true;
                        performLayoutLockedInner();
                    }
                }
@@ -9184,6 +9238,10 @@ public class WindowManagerService extends IWindowManager.Stub
                        w.mLastRequestedHeight = height;
                        w.mLastShownFrame.set(w.mShownFrame);
                        try {
                            if (SHOW_TRANSACTIONS) Log.i(
                                    TAG, "  SURFACE " + w.mSurface
                                    + ": POS " + w.mShownFrame.left
                                    + ", " + w.mShownFrame.top);
                            w.mSurface.setPosition(w.mShownFrame.left, w.mShownFrame.top);
                        } catch (RuntimeException e) {
                            Log.w(TAG, "Error positioning surface in " + w, e);
@@ -9196,14 +9254,6 @@ public class WindowManagerService extends IWindowManager.Stub
                        width = w.mShownFrame.width();
                        height = w.mShownFrame.height();
                        w.mLastShownFrame.set(w.mShownFrame);
                        if (resize) {
                            if (SHOW_TRANSACTIONS) Log.i(
                                    TAG, "  SURFACE " + w.mSurface + ": ("
                                    + w.mShownFrame.left + ","
                                    + w.mShownFrame.top + ") ("
                                    + w.mShownFrame.width() + "x"
                                    + w.mShownFrame.height() + ")");
                        }
                    }

                    if (resize) {
@@ -9211,6 +9261,12 @@ public class WindowManagerService extends IWindowManager.Stub
                        if (height < 1) height = 1;
                        if (w.mSurface != null) {
                            try {
                                if (SHOW_TRANSACTIONS) Log.i(
                                        TAG, "  SURFACE " + w.mSurface + ": POS "
                                        + w.mShownFrame.left + ","
                                        + w.mShownFrame.top + " SIZE "
                                        + w.mShownFrame.width() + "x"
                                        + w.mShownFrame.height());
                                w.mSurface.setSize(width, height);
                                w.mSurface.setPosition(w.mShownFrame.left,
                                        w.mShownFrame.top);
@@ -9239,6 +9295,22 @@ public class WindowManagerService extends IWindowManager.Stub
                            w.mLastFrame.set(w.mFrame);
                            w.mLastContentInsets.set(w.mContentInsets);
                            w.mLastVisibleInsets.set(w.mVisibleInsets);
                            // If the screen is currently frozen, then keep
                            // it frozen until this window draws at its new
                            // orientation.
                            if (mDisplayFrozen) {
                                if (DEBUG_ORIENTATION) Log.v(TAG,
                                        "Resizing while display frozen: " + w);
                                w.mOrientationChanging = true;
                                if (mWindowsFreezingScreen) {
                                    mWindowsFreezingScreen = true;
                                    // XXX should probably keep timeout from
                                    // when we first froze the display.
                                    mH.removeMessages(H.WINDOW_FREEZE_TIMEOUT);
                                    mH.sendMessageDelayed(mH.obtainMessage(
                                            H.WINDOW_FREEZE_TIMEOUT), 2000);
                                }
                            }
                            // If the orientation is changing, then we need to
                            // hold off on unfreezing the display until this
                            // window has been redrawn; to do that, we need
@@ -9340,7 +9412,11 @@ public class WindowManagerService extends IWindowManager.Stub
                        w.mLastVScale = w.mVScale;
                        if (SHOW_TRANSACTIONS) Log.i(
                                TAG, "  SURFACE " + w.mSurface + ": alpha="
                                + w.mShownAlpha + " layer=" + w.mAnimLayer);
                                + w.mShownAlpha + " layer=" + w.mAnimLayer
                                + " matrix=[" + (w.mDsDx*w.mHScale)
                                + "," + (w.mDtDx*w.mVScale)
                                + "][" + (w.mDsDy*w.mHScale)
                                + "," + (w.mDtDy*w.mVScale) + "]");
                        if (w.mSurface != null) {
                            try {
                                w.mSurface.setAlpha(w.mShownAlpha);
@@ -9571,6 +9647,8 @@ public class WindowManagerService extends IWindowManager.Stub
                i--;
                WindowState win = mResizingWindows.get(i);
                try {
                    if (DEBUG_ORIENTATION) Log.v(TAG, "Reporting new frame to "
                            + win + ": " + win.mFrame);
                    win.mClient.resized(win.mFrame.width(),
                            win.mFrame.height(), win.mLastContentInsets,
                            win.mLastVisibleInsets, win.mDrawPending);
@@ -9642,7 +9720,7 @@ public class WindowManagerService extends IWindowManager.Stub
            mH.sendEmptyMessage(H.REPORT_LOSING_FOCUS);
        }
        if (wallpaperDestroyed) {
            needRelayout = adjustWallpaperWindowsLocked();            
            needRelayout = adjustWallpaperWindowsLocked() != 0;
        }
        if (needRelayout) {
            requestAnimationLocked(0);
@@ -9720,7 +9798,7 @@ public class WindowManagerService extends IWindowManager.Stub
                                + " token=" + win.mToken
                                + " pid=" + ws.mSession.mPid
                                + " uid=" + ws.mSession.mUid);
                        ws.mSurface.clear();
                        ws.mSurface.destroy();
                        ws.mSurface = null;
                        mForceRemoves.add(ws);
                        i--;
@@ -9730,7 +9808,7 @@ public class WindowManagerService extends IWindowManager.Stub
                        Log.w(TAG, "LEAKED SURFACE (app token hidden): "
                                + ws + " surface=" + ws.mSurface
                                + " token=" + win.mAppToken);
                        ws.mSurface.clear();
                        ws.mSurface.destroy();
                        ws.mSurface = null;
                        leakedSurface = true;
                    }
@@ -9766,7 +9844,7 @@ public class WindowManagerService extends IWindowManager.Stub
                // surface and ask the app to request another one.
                Log.w(TAG, "Looks like we have reclaimed some memory, clearing surface for retry.");
                if (surface != null) {
                    surface.clear();
                    surface.destroy();
                    win.mSurface = null;
                }

@@ -10025,6 +10103,16 @@ public class WindowManagerService extends IWindowManager.Stub
                    w.dump(pw, "    ");
                }
            }
            if (mResizingWindows.size() > 0) {
                pw.println(" ");
                pw.println("  Windows waiting to resize:");
                for (int i=mResizingWindows.size()-1; i>=0; i--) {
                    WindowState w = mResizingWindows.get(i);
                    pw.print("  Resizing #"); pw.print(i); pw.print(' ');
                            pw.print(w); pw.println(":");
                    w.dump(pw, "    ");
                }
            }
            if (mSessions.size() > 0) {
                pw.println(" ");
                pw.println("  All active sessions:");
@@ -10227,7 +10315,8 @@ public class WindowManagerService extends IWindowManager.Stub
            mDimSurface.setLayer(w.mAnimLayer-1);

            final float target = w.mExiting ? 0 : w.mAttrs.dimAmount;
            if (SHOW_TRANSACTIONS) Log.i(TAG, "layer=" + (w.mAnimLayer-1) + ", target=" + target);
            if (SHOW_TRANSACTIONS) Log.i(TAG, "  DIM " + mDimSurface
                    + ": layer=" + (w.mAnimLayer-1) + " target=" + target);
            if (mDimTargetAlpha != target) {
                // If the desired dim level has changed, then
                // start an animation to it.