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

Commit 5c8b722d authored by Rob Carr's avatar Rob Carr Committed by Android (Google) Code Review
Browse files

Merge changes from topics "scvhpapi", "wwm-api-3"

* changes:
  Unhide SurfaceControlViewHost API
  SurfaceView: Add reparentSurfacePackage method
parents 0868e078 87f5d2cb
Loading
Loading
Loading
Loading
+16 −0
Original line number Diff line number Diff line
@@ -52601,6 +52601,20 @@ package android.view {
    field @NonNull public static final android.os.Parcelable.Creator<android.view.SurfaceControl.Transaction> CREATOR;
  }
  public class SurfaceControlViewHost {
    ctor public SurfaceControlViewHost(@NonNull android.content.Context, @NonNull android.view.Display, @Nullable android.os.IBinder);
    method public void addView(@NonNull android.view.View, int, int);
    method @Nullable public android.view.SurfaceControlViewHost.SurfacePackage getSurfacePackage();
    method public void relayout(int, int);
    method public void release();
  }
  public static final class SurfaceControlViewHost.SurfacePackage implements android.os.Parcelable {
    method public int describeContents();
    method public void writeToParcel(@NonNull android.os.Parcel, int);
    field @NonNull public static final android.os.Parcelable.Creator<android.view.SurfaceControlViewHost.SurfacePackage> CREATOR;
  }
  public interface SurfaceHolder {
    method public void addCallback(android.view.SurfaceHolder.Callback);
    method public android.view.Surface getSurface();
@@ -52645,7 +52659,9 @@ package android.view {
    ctor public SurfaceView(android.content.Context, android.util.AttributeSet, int, int);
    method public boolean gatherTransparentRegion(android.graphics.Region);
    method public android.view.SurfaceHolder getHolder();
    method @Nullable public android.os.IBinder getHostToken();
    method public android.view.SurfaceControl getSurfaceControl();
    method public void setChildSurfacePackage(@NonNull android.view.SurfaceControlViewHost.SurfacePackage);
    method public void setSecure(boolean);
    method public void setZOrderMediaOverlay(boolean);
    method public void setZOrderOnTop(boolean);
+0 −16
Original line number Diff line number Diff line
@@ -4602,22 +4602,6 @@ package android.view {
    method public abstract String asyncImpl() default "";
  }

  public class SurfaceControlViewHost {
    ctor public SurfaceControlViewHost(@NonNull android.content.Context, @NonNull android.view.Display, @Nullable android.os.IBinder);
    method public void addView(android.view.View, android.view.WindowManager.LayoutParams);
    method public void dispose();
    method @Nullable public android.view.SurfaceControlViewHost.SurfacePackage getSurfacePackage();
    method public void relayout(android.view.WindowManager.LayoutParams);
  }

  public class SurfaceControlViewHost.SurfacePackage {
    method @NonNull public android.view.SurfaceControl getSurfaceControl();
  }

  public class SurfaceView extends android.view.View {
    method @Nullable public android.os.IBinder getInputToken();
  }

  @UiThread public class View implements android.view.accessibility.AccessibilityEventSource android.graphics.drawable.Drawable.Callback android.view.KeyEvent.Callback {
    method public android.view.View getTooltipView();
    method public boolean isAutofilled();
+114 −16
Original line number Diff line number Diff line
@@ -20,15 +20,21 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.TestApi;
import android.content.Context;
import android.graphics.PixelFormat;
import android.os.IBinder;
import android.os.Parcel;
import android.os.Parcelable;

/**
 * Utility class for adding a view hierarchy to a SurfaceControl.
 *
 * See WindowlessWmTest for example usage.
 * @hide
 * Utility class for adding a View hierarchy to a {@link SurfaceControl}. The View hierarchy
 * will render in to a root SurfaceControl, and receive input based on the SurfaceControl's
 * placement on-screen. The primary usage of this class is to embed a View hierarchy from
 * one process in to another. After the SurfaceControlViewHost has been set up in the embedded
 * content provider, we can send the {@link SurfaceControlViewHost.SurfacePackage}
 * to the host process. The host process can then attach the hierarchy to a SurfaceView within
 * its own by calling
 * {@link SurfaceView#setChildSurfacePackage}.
 */
@TestApi
public class SurfaceControlViewHost {
    private ViewRootImpl mViewRoot;
    private WindowlessWindowManager mWm;
@@ -36,20 +42,52 @@ public class SurfaceControlViewHost {
    private SurfaceControl mSurfaceControl;

    /**
     * @hide
     * Package encapsulating a Surface hierarchy which contains interactive view
     * elements. It's expected to get this object from
     * {@link SurfaceControlViewHost#getSurfacePackage} afterwards it can be embedded within
     * a SurfaceView by calling {@link SurfaceView#setChildSurfacePackage}.
     */
    @TestApi
    public class SurfacePackage {
        final SurfaceControl mSurfaceControl;
    public static final class SurfacePackage implements Parcelable {
        private final SurfaceControl mSurfaceControl;
        // TODO: Accessibility ID goes here

        SurfacePackage(SurfaceControl sc) {
            mSurfaceControl = sc;
        }

        private SurfacePackage(Parcel in) {
            mSurfaceControl = new SurfaceControl();
            mSurfaceControl.readFromParcel(in);
        }

        /**
         * Use {@link SurfaceView#setChildSurfacePackage} or manually fix
         * accessibility (see SurfaceView implementation).
         * @hide
         */
        public @NonNull SurfaceControl getSurfaceControl() {
            return mSurfaceControl;
        }

        @Override
        public int describeContents() {
            return 0;
        }

        @Override
        public void writeToParcel(@NonNull Parcel out, int flags) {
            mSurfaceControl.writeToParcel(out, flags);
        }

        public static final @NonNull Creator<SurfacePackage> CREATOR
             = new Creator<SurfacePackage>() {
                     public SurfacePackage createFromParcel(Parcel in) {
                         return new SurfacePackage(in);
                     }
                     public SurfacePackage[] newArray(int size) {
                         return new SurfacePackage[size];
                     }
             };
    }

    /** @hide */
@@ -59,17 +97,36 @@ public class SurfaceControlViewHost {
        mViewRoot = new ViewRootImpl(c, d, mWm);
    }

    public SurfaceControlViewHost(@NonNull Context c, @NonNull Display d,
            @Nullable IBinder hostInputToken) {
    /**
     * Construct a new SurfaceControlViewHost. The root Surface will be
     * allocated internally and is accessible via getSurfacePackage().
     *
     * The {@param hostToken} parameter, primarily used for ANR reporting,
     * must be obtained from whomever will be hosting the embedded hierarchy.
     * It's accessible from {@link SurfaceView#getHostToken}.
     *
     * @param context The Context object for your activity or application.
     * @param display The Display the hierarchy will be placed on.
     * @param hostToken The host token, as discussed above.
     */
    public SurfaceControlViewHost(@NonNull Context context, @NonNull Display display,
            @Nullable IBinder hostToken) {
        mSurfaceControl = new SurfaceControl.Builder()
            .setContainerLayer()
            .setName("SurfaceControlViewHost")
            .build();
        mWm = new WindowlessWindowManager(c.getResources().getConfiguration(), mSurfaceControl,
                hostInputToken);
        mViewRoot = new ViewRootImpl(c, d, mWm);
        mWm = new WindowlessWindowManager(context.getResources().getConfiguration(),
                mSurfaceControl, hostToken);
        mViewRoot = new ViewRootImpl(context, display, mWm);
    }

    /**
     * Return a SurfacePackage for the root SurfaceControl of the embedded hierarchy.
     * Rather than be directly reparented using {@link SurfaceControl.Transaction} this
     * SurfacePackage should be passed to {@link SurfaceView#setChildSurfacePackage}
     * which will not only reparent the Surface, but ensure the accessibility hierarchies
     * are linked.
     */
    public @Nullable SurfacePackage getSurfacePackage() {
        if (mSurfaceControl != null) {
            return new SurfacePackage(mSurfaceControl);
@@ -78,10 +135,32 @@ public class SurfaceControlViewHost {
        }
    }

    public void addView(View view, WindowManager.LayoutParams attrs) {
    /**
     * @hide
     */
    public void addView(@NonNull View view, WindowManager.LayoutParams attrs) {
        mViewRoot.setView(view, attrs, null);
    }

    /**
     * Set the root view of the SurfaceControlViewHost. This view will render in to
     * the SurfaceControl, and receive input based on the SurfaceControls positioning on
     * screen. It will be laid as if it were in a window of the passed in width and height.
     *
     * @param view The View to add
     * @param width The width to layout the View within, in pixels.
     * @param height The height to layout the View within, in pixels.
     */
    public void addView(@NonNull View view, int width, int height) {
        final WindowManager.LayoutParams lp =
                new WindowManager.LayoutParams(width, height,
                        WindowManager.LayoutParams.TYPE_APPLICATION, 0, PixelFormat.TRANSPARENT);
        addView(view, lp);
    }

    /**
     * @hide
     */
    public void relayout(WindowManager.LayoutParams attrs) {
        mViewRoot.setLayoutParams(attrs, false);
        mViewRoot.setReportNextDraw();
@@ -90,8 +169,27 @@ public class SurfaceControlViewHost {
        });
    }

    public void dispose() {
    /**
     * Modify the size of the root view.
     *
     * @param width Width in pixels
     * @param height Height in pixels
     */
    public void relayout(int width, int height) {
        final WindowManager.LayoutParams lp =
                new WindowManager.LayoutParams(width, height,
                        WindowManager.LayoutParams.TYPE_APPLICATION, 0, PixelFormat.TRANSPARENT);
        relayout(width, height);
    }

    /**
     * Trigger the tear down of the embedded view hierarchy and release the SurfaceControl.
     * This will result in onDispatchedFromWindow being dispatched to the embedded view hierarchy
     * and render the object unusable.
     */
    public void release() {
        mViewRoot.dispatchDetachedFromWindow();
        mSurfaceControl.release();
    }

    /**
+40 −4
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import static android.view.WindowManagerPolicyConstants.APPLICATION_MEDIA_OVERLA
import static android.view.WindowManagerPolicyConstants.APPLICATION_MEDIA_SUBLAYER;
import static android.view.WindowManagerPolicyConstants.APPLICATION_PANEL_SUBLAYER;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.TestApi;
import android.compat.annotation.UnsupportedAppUsage;
@@ -43,6 +44,7 @@ import android.util.AttributeSet;
import android.util.Log;
import android.view.SurfaceControl.Transaction;
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.SurfaceControlViewHost;

import com.android.internal.view.SurfaceCallbackHelper;

@@ -204,6 +206,7 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall

    // The token of embedded windowless view hierarchy.
    private IBinder mEmbeddedViewHierarchy;
    SurfaceControlViewHost.SurfacePackage mSurfacePackage;

    public SurfaceView(Context context) {
        this(context, null);
@@ -877,6 +880,11 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
                    } else {
                        mTmpTransaction.hide(mSurfaceControl);
                    }

                    if (mSurfacePackage != null) {
                        reparentSurfacePackage(mTmpTransaction, mSurfacePackage);
                    }

                    updateBackgroundVisibility(mTmpTransaction);
                    if (mUseAlpha) {
                        mTmpTransaction.setAlpha(mSurfaceControl, alpha);
@@ -1471,11 +1479,12 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
    }

    /**
     * @return The token used to identify the windows input channel.
     * @hide
     * A token used for constructing {@link SurfaceControlViewHost}. This token should
     * be passed from the host process to the client process.
     *
     * @return The token
     */
    @TestApi
    public @Nullable IBinder getInputToken() {
    public @Nullable IBinder getHostToken() {
        final ViewRootImpl viewRoot = getViewRootImpl();
        if (viewRoot == null) {
            return null;
@@ -1536,6 +1545,33 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
        viewRoot.setUseBLASTSyncTransaction();
    }

    /**
     * Display the view-hierarchy embedded within a {@link SurfaceControlViewHost.SurfacePackage}
     * within this SurfaceView. If this SurfaceView is above it's host Surface (see
     * {@link #setZOrderOnTop} then the embedded Surface hierarchy will be able to receive
     * input.
     *
     * @param p The SurfacePackage to embed.
     */
    public void setChildSurfacePackage(@NonNull SurfaceControlViewHost.SurfacePackage p) {
        final SurfaceControl sc = p != null ? p.getSurfaceControl() : null;
        final SurfaceControl lastSc = mSurfacePackage != null ?
            mSurfacePackage.getSurfaceControl() : null;
        if (mSurfaceControl != null && lastSc != null) {
            mTmpTransaction.reparent(lastSc, null).apply();
        } else if (mSurfaceControl != null) {
            reparentSurfacePackage(mTmpTransaction, p);
            mTmpTransaction.apply();
        }
        mSurfacePackage = p;
    }

    private void reparentSurfacePackage(SurfaceControl.Transaction t,
            SurfaceControlViewHost.SurfacePackage p) {
        // TODO: Link accessibility IDs here.
        t.reparent(p.getSurfaceControl(), mSurfaceControl);
    }

    /**
     * Add the token of embedded view hierarchy. Set {@code null} to clear the embedded view
     * hierarchy.
+1 −1
Original line number Diff line number Diff line
@@ -37,7 +37,7 @@ public final class UniversalSmartspaceUtils {
        Intent intent = new Intent(ACTION_REQUEST_SMARTSPACE_VIEW);

        Bundle inputBundle = new Bundle();
        inputBundle.putBinder(BUNDLE_KEY_INPUT_TOKEN, surfaceView.getInputToken());
        inputBundle.putBinder(BUNDLE_KEY_INPUT_TOKEN, surfaceView.getHostToken());
        return intent
                .putExtra(INTENT_KEY_SURFACE_CONTROL, surfaceView.getSurfaceControl())
                .putExtra(INTENT_KEY_INPUT_BUNDLE, inputBundle)
Loading