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

Commit 3f09bb3f authored by Evan Rosky's avatar Evan Rosky
Browse files

Add some lifecycle functionality to WindowlessWM

This adds other parts of the window lifecycle (eg. ViewRoot
death, window removal, layout update). Some of the lifecycle
controls are just utilities, but are needed so that they
can be performed out-of-package.

It also shows/hides the surface based on underlying view
visibility. In actual WM, the surface is actually created/
destroyed based on visibility, but this breaks continuity
in WWM because the WWM user should have full control over
it.

Also made this public so it can be subclassed.

Bug: 133381284
Test: manual test in later CLs
Change-Id: Ibd7792c3f52c216089d9b498e3770e100ff24642
parent 58bea80f
Loading
Loading
Loading
Loading
+16 −0
Original line number Diff line number Diff line
@@ -32,6 +32,14 @@ import android.os.IBinder;
public class WindowlessViewRoot {
    private ViewRootImpl mViewRoot;
    private WindowlessWindowManager mWm;

    /** @hide */
    public WindowlessViewRoot(@NonNull Context c, @NonNull Display d,
            @NonNull WindowlessWindowManager wwm) {
        mWm = wwm;
        mViewRoot = new ViewRootImpl(c, d, mWm);
    }

    public WindowlessViewRoot(@NonNull Context c, @NonNull Display d,
            @NonNull SurfaceControl rootSurface,
            @Nullable IBinder hostInputToken) {
@@ -55,4 +63,12 @@ public class WindowlessViewRoot {
    public void dispose() {
        mViewRoot.dispatchDetachedFromWindow();
    }

    /**
     * Tell this viewroot to clean itself up.
     * @hide
     */
    public void die() {
        mViewRoot.die(false /* immediate */);
    }
}
+27 −6
Original line number Diff line number Diff line
@@ -34,7 +34,7 @@ import java.util.HashMap;
* By parcelling the root surface, the app can offer another app content for embedding.
* @hide
*/
class WindowlessWindowManager implements IWindowSession {
public class WindowlessWindowManager implements IWindowSession {
    private final static String TAG = "WindowlessWindowManager";

    private class State {
@@ -45,6 +45,7 @@ class WindowlessWindowManager implements IWindowSession {
            mParams.copyFrom(p);
        }
    };

    /**
     * Used to store SurfaceControl we've built for clients to
     * reconfigure them if relayout is called.
@@ -67,13 +68,18 @@ class WindowlessWindowManager implements IWindowSession {
    private int mForceHeight = -1;
    private int mForceWidth = -1;

    WindowlessWindowManager(Configuration c, SurfaceControl rootSurface, IBinder hostInputToken) {
    public WindowlessWindowManager(Configuration c, SurfaceControl rootSurface,
            IBinder hostInputToken) {
        mRootSurface = rootSurface;
        mConfiguration = new Configuration(c);
        mRealWm = WindowManagerGlobal.getWindowSession();
        mHostInputToken = hostInputToken;
    }

    protected void setConfiguration(Configuration configuration) {
        mConfiguration.setTo(configuration);
    }

    /**
     * Utility API.
     */
@@ -125,6 +131,17 @@ class WindowlessWindowManager implements IWindowSession {
    @Override
    public void remove(android.view.IWindow window) throws RemoteException {
        mRealWm.remove(window);
        State state;
        synchronized (this) {
            state = mStateForWindow.remove(window.asBinder());
        }
        if (state == null) {
            throw new IllegalArgumentException(
                    "Invalid window token (never added or removed already)");
        }
        try (SurfaceControl.Transaction t = new SurfaceControl.Transaction()) {
            t.remove(state.mSurfaceControl).apply();
        }
    }

    private boolean isOpaque(WindowManager.LayoutParams attrs) {
@@ -165,10 +182,14 @@ class WindowlessWindowManager implements IWindowSession {
        int height = surfaceInsets != null ?
                attrs.height + surfaceInsets.top + surfaceInsets.bottom : attrs.height;

        t.show(sc)
            .setBufferSize(sc, width, height)
            .setOpaque(sc, isOpaque(attrs))
            .apply();
        t.setBufferSize(sc, width, height)
            .setOpaque(sc, isOpaque(attrs));
        if (viewFlags == View.VISIBLE) {
            t.show(sc);
        } else {
            t.hide(sc);
        }
        t.apply();
        outSurfaceControl.copyFrom(sc);
        outFrame.set(0, 0, attrs.width, attrs.height);