diff options
author | Robert Carr <racarr@google.com> | 2020-01-19 17:27:00 -0800 |
---|---|---|
committer | Robert Carr <racarr@google.com> | 2020-01-22 12:54:06 -0800 |
commit | 87f5d2cb7830d546c4094cb76b183c77f2b615e6 (patch) | |
tree | 8a73a6a760051b9f736f16578d93818a6b65043d | |
parent | 30ad618cfef9dd7fad12b14d7e0bdadb5d68cb82 (diff) |
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
7 files changed, 144 insertions, 42 deletions
diff --git a/api/current.txt b/api/current.txt index 74242ba42426..104fd9b23f9a 100644 --- a/api/current.txt +++ b/api/current.txt @@ -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); diff --git a/api/test-current.txt b/api/test-current.txt index f3930b850e0d..eb0ca5d9cff9 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -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(); diff --git a/core/java/android/view/SurfaceControlViewHost.java b/core/java/android/view/SurfaceControlViewHost.java index 4f8aecd08f6d..71cf051a4e08 100644 --- a/core/java/android/view/SurfaceControlViewHost.java +++ b/core/java/android/view/SurfaceControlViewHost.java @@ -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(); } /** diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java index db1c1612ce72..1981bdd93eeb 100644 --- a/core/java/android/view/SurfaceView.java +++ b/core/java/android/view/SurfaceView.java @@ -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 ? diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/UniversalSmartspaceUtils.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/UniversalSmartspaceUtils.java index 70a464dd254c..871cae3b4f8d 100644 --- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/UniversalSmartspaceUtils.java +++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/UniversalSmartspaceUtils.java @@ -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) diff --git a/packages/SystemUI/src/com/android/keyguard/AdminSecondaryLockScreenController.java b/packages/SystemUI/src/com/android/keyguard/AdminSecondaryLockScreenController.java index 2f8ef2dc8828..b2423b9bf252 100644 --- a/packages/SystemUI/src/com/android/keyguard/AdminSecondaryLockScreenController.java +++ b/packages/SystemUI/src/com/android/keyguard/AdminSecondaryLockScreenController.java @@ -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()); diff --git a/tests/SurfaceControlViewHostTest/src/com/android/test/viewembed/SurfaceControlViewHostTest.java b/tests/SurfaceControlViewHostTest/src/com/android/test/viewembed/SurfaceControlViewHostTest.java index 4c8221c813b4..61696718c76e 100644 --- a/tests/SurfaceControlViewHostTest/src/com/android/test/viewembed/SurfaceControlViewHostTest.java +++ b/tests/SurfaceControlViewHostTest/src/com/android/test/viewembed/SurfaceControlViewHostTest.java @@ -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()); |