Unhide SurfaceControlViewHost API

Unhide the SurfaceControlViewHost API and the getHostToken/setChildSurfacePackage
API's required to use them.

Bug: 134365580
Bug: 140587144
Test: WindowlessWmTests
Change-Id: I0c5af2166f1d87947f54a492fd0b887c6253b9fe
This commit is contained in:
Robert Carr
2020-01-19 17:27:00 -08:00
parent 30ad618cfe
commit 87f5d2cb78
7 changed files with 144 additions and 42 deletions

View File

@@ -52456,6 +52456,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();
@@ -52500,7 +52514,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);

View File

@@ -4411,23 +4411,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();
method public void setChildSurfacePackage(@NonNull android.view.SurfaceControlViewHost.SurfacePackage);
}
@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();

View File

@@ -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();
}
/**

View File

@@ -1479,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;
@@ -1545,9 +1546,13 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall
}
/**
* @hide
* 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.
*/
@TestApi
public void setChildSurfacePackage(@NonNull SurfaceControlViewHost.SurfacePackage p) {
final SurfaceControl sc = p != null ? p.getSurfaceControl() : null;
final SurfaceControl lastSc = mSurfacePackage != null ?

View File

@@ -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)

View File

@@ -172,7 +172,7 @@ public class AdminSecondaryLockScreenController {
private void onSurfaceReady() {
try {
mClient.onSurfaceReady(mView.getInputToken(), mCallback);
mClient.onSurfaceReady(mView.getHostToken(), mCallback);
} catch (RemoteException e) {
Log.e(TAG, "Error in onSurfaceReady", e);
dismiss(KeyguardUpdateMonitor.getCurrentUser());

View File

@@ -52,7 +52,7 @@ public class SurfaceControlViewHostTest extends Activity implements SurfaceHolde
void addEmbeddedView() {
mVr = new SurfaceControlViewHost(this, this.getDisplay(),
mView.getInputToken());
mView.getHostToken());
mView.setChildSurfacePackage(mVr.getSurfacePackage());