Loading api/current.txt +14 −1 Original line number Diff line number Diff line Loading @@ -56772,6 +56772,19 @@ package android.view.contentcapture { package android.view.inline { public class InlineContentView extends android.view.ViewGroup { method @Nullable public android.view.SurfaceControl getSurfaceControl(); method public boolean isZOrderedOnTop(); method public void onLayout(boolean, int, int, int, int); method public void setSurfaceControlCallback(@Nullable android.view.inline.InlineContentView.SurfaceControlCallback); method public boolean setZOrderedOnTop(boolean); } public static interface InlineContentView.SurfaceControlCallback { method public void onCreated(@NonNull android.view.SurfaceControl); method public void onDestroyed(@NonNull android.view.SurfaceControl); } public final class InlinePresentationSpec implements android.os.Parcelable { method public int describeContents(); method @NonNull public android.util.Size getMaxSize(); Loading Loading @@ -56960,7 +56973,7 @@ package android.view.inputmethod { public final class InlineSuggestion implements android.os.Parcelable { method public int describeContents(); method @NonNull public android.view.inputmethod.InlineSuggestionInfo getInfo(); method public void inflate(@NonNull android.content.Context, @NonNull android.util.Size, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<android.view.View>); method public void inflate(@NonNull android.content.Context, @NonNull android.util.Size, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<android.view.inline.InlineContentView>); method public void writeToParcel(@NonNull android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator<android.view.inputmethod.InlineSuggestion> CREATOR; } core/java/android/service/autofill/InlineSuggestionRoot.java +3 −1 Original line number Diff line number Diff line Loading @@ -68,7 +68,9 @@ public class InlineSuggestionRoot extends FrameLayout { case MotionEvent.ACTION_MOVE: { final float distance = MathUtils.dist(mDownX, mDownY, event.getX(), event.getY()); if (distance > mTouchSlop) { final boolean isSecure = (event.getFlags() & MotionEvent.FLAG_WINDOW_IS_PARTIALLY_OBSCURED) == 0; if (!isSecure || distance > mTouchSlop) { try { mCallback.onTransferTouchFocusToImeWindow(getViewRootImpl().getInputToken(), getContext().getDisplayId()); Loading core/java/android/view/SurfaceView.java +94 −3 Original line number Diff line number Diff line Loading @@ -686,16 +686,107 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall * SurfaceView is in will be visible on top of its surface. * * <p>Note that this must be set before the surface view's containing * window is attached to the window manager. * window is attached to the window manager. If you target {@link Build.VERSION_CODES#R} * the Z ordering can be changed dynamically if the backing surface is * created, otherwise it would be applied at surface construction time. * * <p>Calling this overrides any previous call to {@link #setZOrderMediaOverlay}. * * @param onTop Whether to show the surface on top of this view's window. */ public void setZOrderOnTop(boolean onTop) { // In R and above we allow dynamic layer changes. final boolean allowDynamicChange = getContext().getApplicationInfo().targetSdkVersion > Build.VERSION_CODES.Q; setZOrderedOnTop(onTop, allowDynamicChange); } /** * @return Whether the surface backing this view appears on top of its parent. * * @hide */ public boolean isZOrderedOnTop() { return mSubLayer > 0; } /** * Controls whether the surface view's surface is placed on top of its * window. Normally it is placed behind the window, to allow it to * (for the most part) appear to composite with the views in the * hierarchy. By setting this, you cause it to be placed above the * window. This means that none of the contents of the window this * SurfaceView is in will be visible on top of its surface. * * <p>Calling this overrides any previous call to {@link #setZOrderMediaOverlay}. * * @param onTop Whether to show the surface on top of this view's window. * @param allowDynamicChange Whether this can happen after the surface is created. * @return Whether the Z ordering changed. * * @hide */ public boolean setZOrderedOnTop(boolean onTop, boolean allowDynamicChange) { final int subLayer; if (onTop) { mSubLayer = APPLICATION_PANEL_SUBLAYER; subLayer = APPLICATION_PANEL_SUBLAYER; } else { mSubLayer = APPLICATION_MEDIA_SUBLAYER; subLayer = APPLICATION_MEDIA_SUBLAYER; } if (mSubLayer == subLayer) { return false; } mSubLayer = subLayer; if (!allowDynamicChange) { return false; } if (mSurfaceControl == null) { return true; } final ViewRootImpl viewRoot = getViewRootImpl(); if (viewRoot == null) { return true; } final Surface parent = viewRoot.mSurface; if (parent == null || !parent.isValid()) { return true; } /* * Schedule a callback that reflects an alpha value onto the underlying surfaces. * This gets called on a RenderThread worker thread, so members accessed here must * be protected by a lock. */ final boolean useBLAST = viewRoot.useBLAST(); viewRoot.registerRtFrameCallback(frame -> { try { final SurfaceControl.Transaction t = useBLAST ? viewRoot.getBLASTSyncTransaction() : new SurfaceControl.Transaction(); synchronized (mSurfaceControlLock) { if (!parent.isValid() || mSurfaceControl == null) { return; } updateRelativeZ(t); if (!useBLAST) { t.deferTransactionUntil(mSurfaceControl, viewRoot.getRenderSurfaceControl(), frame); } } // It's possible that mSurfaceControl is released in the UI thread before // the transaction completes. If that happens, an exception is thrown, which // must be caught immediately. t.apply(); } catch (Exception e) { Log.e(TAG, System.identityHashCode(this) + "setZOrderOnTop RT: Exception during surface transaction", e); } }); invalidate(); return true; } /** Loading core/java/android/view/inline/InlineContentView.java +177 −10 Original line number Diff line number Diff line /* * Copyright (C) 2019 The Android Open Source Project * Copyright (C) 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. Loading @@ -17,22 +17,189 @@ package android.view.inline; import android.annotation.NonNull; import android.annotation.Nullable; import android.content.Context; import android.graphics.PixelFormat; import android.util.AttributeSet; import android.view.SurfaceControl; import android.view.SurfaceControlViewHost; import android.view.SurfaceHolder; import android.view.SurfaceView; import android.view.ViewGroup; /** * This class represents a view that can hold an opaque content that may be from a different source. * This class represents a view that holds opaque content from another app that * you can inline in your UI. * * <p>Since the content presented by this view is from another security domain,it is * shown on a remote surface preventing the host application from accessing that content. * Also the host application cannot interact with the inlined content by injecting touch * events or clicking programmatically. * * <p>This view can be overlaid by other windows, i.e. redressed, but if this is the case * the inined UI would not be interactive. Sometimes this is desirable, e.g. animating * transitions. * * <p>By default the surface backing this view is shown on top of the hosting window such * that the inlined content is interactive. However, you can temporarily move the surface * under the hosting window which could be useful in some cases, e.g. animating transitions. * At this point the inlined content will not be interactive and the touch events would * be delivered to your app. */ public class InlineContentView extends ViewGroup { /** * Callback for observing the lifecycle of the surface control * that manipulates the backing secure embedded UI surface. */ public interface SurfaceControlCallback { /** * Called when the backing surface is being created. * * @param surfaceControl The surface control to manipulate the surface. */ void onCreated(@NonNull SurfaceControl surfaceControl); /** * Called when the backing surface is being destroyed. * * @param surfaceControl The surface control to manipulate the surface. */ void onDestroyed(@NonNull SurfaceControl surfaceControl); } private final @NonNull SurfaceHolder.Callback mSurfaceCallback = new SurfaceHolder.Callback() { @Override public void surfaceCreated(@NonNull SurfaceHolder holder) { mSurfaceControlCallback.onCreated(mSurfaceView.getSurfaceControl()); } @Override public void surfaceChanged(@NonNull SurfaceHolder holder, int format, int width, int height) { /* do nothing */ } @Override public void surfaceDestroyed(@NonNull SurfaceHolder holder) { mSurfaceControlCallback.onDestroyed(mSurfaceView.getSurfaceControl()); } }; private final @NonNull SurfaceView mSurfaceView; private @Nullable SurfaceControlCallback mSurfaceControlCallback; /** * @inheritDoc * * @hide */ public InlineContentView(@NonNull Context context) { this(context, null); } /** * @inheritDoc * * @hide */ public InlineContentView(@NonNull Context context, @Nullable AttributeSet attrs) { this(context, attrs, 0); } /** * @inheritDoc * * @hide */ public InlineContentView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) { this(context, attrs, defStyleAttr, 0); } /** * Gets the surface control. If the surface is not created this method * returns {@code null}. * * @return The surface control. * * @see #setSurfaceControlCallback(SurfaceControlCallback) */ public @Nullable SurfaceControl getSurfaceControl() { return mSurfaceView.getSurfaceControl(); } /** * @inheritDoc * * @hide */ public class InlineContentView extends SurfaceView { public InlineContentView(@NonNull Context context, @NonNull SurfaceControlViewHost.SurfacePackage surfacePackage) { super(context); setZOrderOnTop(true); setChildSurfacePackage(surfacePackage); getHolder().setFormat(PixelFormat.TRANSPARENT); public InlineContentView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); mSurfaceView = new SurfaceView(context, attrs, defStyleAttr, defStyleRes); mSurfaceView.setZOrderOnTop(true); mSurfaceView.getHolder().setFormat(PixelFormat.TRANSPARENT); addView(mSurfaceView); } /** * Sets the embedded UI. * @param surfacePackage The embedded UI. * * @hide */ public void setChildSurfacePackage( @Nullable SurfaceControlViewHost.SurfacePackage surfacePackage) { mSurfaceView.setChildSurfacePackage(surfacePackage); } @Override public void onLayout(boolean changed, int l, int t, int r, int b) { mSurfaceView.layout(l, t, r, b); } /** * Sets a callback to observe the lifecycle of the surface control for * managing the backing surface. * * @param callback The callback to set or {@code null} to clear. */ public void setSurfaceControlCallback(@Nullable SurfaceControlCallback callback) { if (mSurfaceControlCallback != null) { mSurfaceView.getHolder().removeCallback(mSurfaceCallback); } mSurfaceControlCallback = callback; if (mSurfaceControlCallback != null) { mSurfaceView.getHolder().addCallback(mSurfaceCallback); } } /** * @return Whether the surface backing this view appears on top of its parent. * * @see #setZOrderedOnTop(boolean) */ public boolean isZOrderedOnTop() { return mSurfaceView.isZOrderedOnTop(); } /** * Controls whether the backing surface is placed on top of this view's window. * Normally, it is placed on top of the window, to allow interaction * with the inlined UI. Via this method, you can place the surface below the * window. This means that all of the contents of the window this view is in * will be visible on top of its surface. * * <p> The Z ordering can be changed dynamically if the backing surface is * created, otherwise the ordering would be applied at surface construction time. * * @param onTop Whether to show the surface on top of this view's window. * * @see #isZOrderedOnTop() */ public boolean setZOrderedOnTop(boolean onTop) { return mSurfaceView.setZOrderedOnTop(onTop, /*allowDynamicChange*/ true); } } core/java/android/view/inputmethod/InlineSuggestion.java +12 −12 Original line number Diff line number Diff line Loading @@ -29,7 +29,6 @@ import android.os.RemoteException; import android.util.Size; import android.util.Slog; import android.view.SurfaceControlViewHost; import android.view.View; import android.view.inline.InlineContentView; import android.view.inline.InlinePresentationSpec; Loading Loading @@ -94,15 +93,15 @@ public final class InlineSuggestion implements Parcelable { this(info, contentProvider, /* inlineContentCallback */ null); } /** * Inflates a view with the content of this suggestion at a specific size. * The size must be between the {@link InlinePresentationSpec#getMinSize() min size} * and the {@link InlinePresentationSpec#getMaxSize() max size} of the presentation * spec returned by {@link InlineSuggestionInfo#getPresentationSpec()}. * * <p> The caller can attach an {@link View.OnClickListener} and/or an * {@link View.OnLongClickListener} to the view in the {@code callback} to receive click and * <p> The caller can attach an {@link android.view.View.OnClickListener} and/or an * {@link android.view.View.OnLongClickListener} to the view in the * {@code callback} to receive click and * long click events on the view. * * @param context Context in which to inflate the view. Loading @@ -113,7 +112,7 @@ public final class InlineSuggestion implements Parcelable { */ public void inflate(@NonNull Context context, @NonNull Size size, @NonNull @CallbackExecutor Executor callbackExecutor, @NonNull Consumer<View> callback) { @NonNull Consumer<InlineContentView> callback) { final Size minSize = mInfo.getPresentationSpec().getMinSize(); final Size maxSize = mInfo.getPresentationSpec().getMaxSize(); if (size.getHeight() < minSize.getHeight() || size.getHeight() > maxSize.getHeight() Loading @@ -138,7 +137,7 @@ public final class InlineSuggestion implements Parcelable { } private synchronized InlineContentCallbackImpl getInlineContentCallback(Context context, Executor callbackExecutor, Consumer<View> callback) { Executor callbackExecutor, Consumer<InlineContentView> callback) { if (mInlineContentCallback != null) { throw new IllegalStateException("Already called #inflate()"); } Loading Loading @@ -185,12 +184,12 @@ public final class InlineSuggestion implements Parcelable { private final @NonNull Context mContext; private final @NonNull Executor mCallbackExecutor; private final @NonNull Consumer<View> mCallback; private @Nullable View mView; private final @NonNull Consumer<InlineContentView> mCallback; private @Nullable InlineContentView mView; InlineContentCallbackImpl(@NonNull Context context, @NonNull @CallbackExecutor Executor callbackExecutor, @NonNull Consumer<View> callback) { @NonNull Consumer<InlineContentView> callback) { mContext = context; mCallbackExecutor = callbackExecutor; mCallback = callback; Loading @@ -201,7 +200,8 @@ public final class InlineSuggestion implements Parcelable { if (content == null) { mCallbackExecutor.execute(() -> mCallback.accept(/* view */null)); } else { mView = new InlineContentView(mContext, content); mView = new InlineContentView(mContext); mView.setChildSurfacePackage(content); mCallbackExecutor.execute(() -> mCallback.accept(mView)); } } Loading Loading @@ -398,10 +398,10 @@ public final class InlineSuggestion implements Parcelable { }; @DataClass.Generated( time = 1583889058241L, time = 1584679775946L, codegenVersion = "1.0.15", sourceFile = "frameworks/base/core/java/android/view/inputmethod/InlineSuggestion.java", inputSignatures = "private static final java.lang.String TAG\nprivate final @android.annotation.NonNull android.view.inputmethod.InlineSuggestionInfo mInfo\nprivate final @android.annotation.Nullable com.android.internal.view.inline.IInlineContentProvider mContentProvider\nprivate @com.android.internal.util.DataClass.ParcelWith(android.view.inputmethod.InlineSuggestion.InlineContentCallbackImplParceling.class) @android.annotation.Nullable android.view.inputmethod.InlineSuggestion.InlineContentCallbackImpl mInlineContentCallback\npublic static @android.annotation.TestApi @android.annotation.NonNull android.view.inputmethod.InlineSuggestion newInlineSuggestion(android.view.inputmethod.InlineSuggestionInfo)\npublic void inflate(android.content.Context,android.util.Size,java.util.concurrent.Executor,java.util.function.Consumer<android.view.View>)\nprivate synchronized android.view.inputmethod.InlineSuggestion.InlineContentCallbackImpl getInlineContentCallback(android.content.Context,java.util.concurrent.Executor,java.util.function.Consumer<android.view.View>)\nclass InlineSuggestion extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genEqualsHashCode=true, genToString=true, genHiddenConstDefs=true, genHiddenConstructor=true)") inputSignatures = "private static final java.lang.String TAG\nprivate final @android.annotation.NonNull android.view.inputmethod.InlineSuggestionInfo mInfo\nprivate final @android.annotation.Nullable com.android.internal.view.inline.IInlineContentProvider mContentProvider\nprivate @com.android.internal.util.DataClass.ParcelWith(android.view.inputmethod.InlineSuggestion.InlineContentCallbackImplParceling.class) @android.annotation.Nullable android.view.inputmethod.InlineSuggestion.InlineContentCallbackImpl mInlineContentCallback\npublic static @android.annotation.TestApi @android.annotation.NonNull android.view.inputmethod.InlineSuggestion newInlineSuggestion(android.view.inputmethod.InlineSuggestionInfo)\npublic void inflate(android.content.Context,android.util.Size,java.util.concurrent.Executor,java.util.function.Consumer<android.view.inline.InlineContentView>)\nprivate synchronized android.view.inputmethod.InlineSuggestion.InlineContentCallbackImpl getInlineContentCallback(android.content.Context,java.util.concurrent.Executor,java.util.function.Consumer<android.view.inline.InlineContentView>)\nclass InlineSuggestion extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genEqualsHashCode=true, genToString=true, genHiddenConstDefs=true, genHiddenConstructor=true)") @Deprecated private void __metadata() {} Loading Loading
api/current.txt +14 −1 Original line number Diff line number Diff line Loading @@ -56772,6 +56772,19 @@ package android.view.contentcapture { package android.view.inline { public class InlineContentView extends android.view.ViewGroup { method @Nullable public android.view.SurfaceControl getSurfaceControl(); method public boolean isZOrderedOnTop(); method public void onLayout(boolean, int, int, int, int); method public void setSurfaceControlCallback(@Nullable android.view.inline.InlineContentView.SurfaceControlCallback); method public boolean setZOrderedOnTop(boolean); } public static interface InlineContentView.SurfaceControlCallback { method public void onCreated(@NonNull android.view.SurfaceControl); method public void onDestroyed(@NonNull android.view.SurfaceControl); } public final class InlinePresentationSpec implements android.os.Parcelable { method public int describeContents(); method @NonNull public android.util.Size getMaxSize(); Loading Loading @@ -56960,7 +56973,7 @@ package android.view.inputmethod { public final class InlineSuggestion implements android.os.Parcelable { method public int describeContents(); method @NonNull public android.view.inputmethod.InlineSuggestionInfo getInfo(); method public void inflate(@NonNull android.content.Context, @NonNull android.util.Size, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<android.view.View>); method public void inflate(@NonNull android.content.Context, @NonNull android.util.Size, @NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<android.view.inline.InlineContentView>); method public void writeToParcel(@NonNull android.os.Parcel, int); field @NonNull public static final android.os.Parcelable.Creator<android.view.inputmethod.InlineSuggestion> CREATOR; }
core/java/android/service/autofill/InlineSuggestionRoot.java +3 −1 Original line number Diff line number Diff line Loading @@ -68,7 +68,9 @@ public class InlineSuggestionRoot extends FrameLayout { case MotionEvent.ACTION_MOVE: { final float distance = MathUtils.dist(mDownX, mDownY, event.getX(), event.getY()); if (distance > mTouchSlop) { final boolean isSecure = (event.getFlags() & MotionEvent.FLAG_WINDOW_IS_PARTIALLY_OBSCURED) == 0; if (!isSecure || distance > mTouchSlop) { try { mCallback.onTransferTouchFocusToImeWindow(getViewRootImpl().getInputToken(), getContext().getDisplayId()); Loading
core/java/android/view/SurfaceView.java +94 −3 Original line number Diff line number Diff line Loading @@ -686,16 +686,107 @@ public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCall * SurfaceView is in will be visible on top of its surface. * * <p>Note that this must be set before the surface view's containing * window is attached to the window manager. * window is attached to the window manager. If you target {@link Build.VERSION_CODES#R} * the Z ordering can be changed dynamically if the backing surface is * created, otherwise it would be applied at surface construction time. * * <p>Calling this overrides any previous call to {@link #setZOrderMediaOverlay}. * * @param onTop Whether to show the surface on top of this view's window. */ public void setZOrderOnTop(boolean onTop) { // In R and above we allow dynamic layer changes. final boolean allowDynamicChange = getContext().getApplicationInfo().targetSdkVersion > Build.VERSION_CODES.Q; setZOrderedOnTop(onTop, allowDynamicChange); } /** * @return Whether the surface backing this view appears on top of its parent. * * @hide */ public boolean isZOrderedOnTop() { return mSubLayer > 0; } /** * Controls whether the surface view's surface is placed on top of its * window. Normally it is placed behind the window, to allow it to * (for the most part) appear to composite with the views in the * hierarchy. By setting this, you cause it to be placed above the * window. This means that none of the contents of the window this * SurfaceView is in will be visible on top of its surface. * * <p>Calling this overrides any previous call to {@link #setZOrderMediaOverlay}. * * @param onTop Whether to show the surface on top of this view's window. * @param allowDynamicChange Whether this can happen after the surface is created. * @return Whether the Z ordering changed. * * @hide */ public boolean setZOrderedOnTop(boolean onTop, boolean allowDynamicChange) { final int subLayer; if (onTop) { mSubLayer = APPLICATION_PANEL_SUBLAYER; subLayer = APPLICATION_PANEL_SUBLAYER; } else { mSubLayer = APPLICATION_MEDIA_SUBLAYER; subLayer = APPLICATION_MEDIA_SUBLAYER; } if (mSubLayer == subLayer) { return false; } mSubLayer = subLayer; if (!allowDynamicChange) { return false; } if (mSurfaceControl == null) { return true; } final ViewRootImpl viewRoot = getViewRootImpl(); if (viewRoot == null) { return true; } final Surface parent = viewRoot.mSurface; if (parent == null || !parent.isValid()) { return true; } /* * Schedule a callback that reflects an alpha value onto the underlying surfaces. * This gets called on a RenderThread worker thread, so members accessed here must * be protected by a lock. */ final boolean useBLAST = viewRoot.useBLAST(); viewRoot.registerRtFrameCallback(frame -> { try { final SurfaceControl.Transaction t = useBLAST ? viewRoot.getBLASTSyncTransaction() : new SurfaceControl.Transaction(); synchronized (mSurfaceControlLock) { if (!parent.isValid() || mSurfaceControl == null) { return; } updateRelativeZ(t); if (!useBLAST) { t.deferTransactionUntil(mSurfaceControl, viewRoot.getRenderSurfaceControl(), frame); } } // It's possible that mSurfaceControl is released in the UI thread before // the transaction completes. If that happens, an exception is thrown, which // must be caught immediately. t.apply(); } catch (Exception e) { Log.e(TAG, System.identityHashCode(this) + "setZOrderOnTop RT: Exception during surface transaction", e); } }); invalidate(); return true; } /** Loading
core/java/android/view/inline/InlineContentView.java +177 −10 Original line number Diff line number Diff line /* * Copyright (C) 2019 The Android Open Source Project * Copyright (C) 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. Loading @@ -17,22 +17,189 @@ package android.view.inline; import android.annotation.NonNull; import android.annotation.Nullable; import android.content.Context; import android.graphics.PixelFormat; import android.util.AttributeSet; import android.view.SurfaceControl; import android.view.SurfaceControlViewHost; import android.view.SurfaceHolder; import android.view.SurfaceView; import android.view.ViewGroup; /** * This class represents a view that can hold an opaque content that may be from a different source. * This class represents a view that holds opaque content from another app that * you can inline in your UI. * * <p>Since the content presented by this view is from another security domain,it is * shown on a remote surface preventing the host application from accessing that content. * Also the host application cannot interact with the inlined content by injecting touch * events or clicking programmatically. * * <p>This view can be overlaid by other windows, i.e. redressed, but if this is the case * the inined UI would not be interactive. Sometimes this is desirable, e.g. animating * transitions. * * <p>By default the surface backing this view is shown on top of the hosting window such * that the inlined content is interactive. However, you can temporarily move the surface * under the hosting window which could be useful in some cases, e.g. animating transitions. * At this point the inlined content will not be interactive and the touch events would * be delivered to your app. */ public class InlineContentView extends ViewGroup { /** * Callback for observing the lifecycle of the surface control * that manipulates the backing secure embedded UI surface. */ public interface SurfaceControlCallback { /** * Called when the backing surface is being created. * * @param surfaceControl The surface control to manipulate the surface. */ void onCreated(@NonNull SurfaceControl surfaceControl); /** * Called when the backing surface is being destroyed. * * @param surfaceControl The surface control to manipulate the surface. */ void onDestroyed(@NonNull SurfaceControl surfaceControl); } private final @NonNull SurfaceHolder.Callback mSurfaceCallback = new SurfaceHolder.Callback() { @Override public void surfaceCreated(@NonNull SurfaceHolder holder) { mSurfaceControlCallback.onCreated(mSurfaceView.getSurfaceControl()); } @Override public void surfaceChanged(@NonNull SurfaceHolder holder, int format, int width, int height) { /* do nothing */ } @Override public void surfaceDestroyed(@NonNull SurfaceHolder holder) { mSurfaceControlCallback.onDestroyed(mSurfaceView.getSurfaceControl()); } }; private final @NonNull SurfaceView mSurfaceView; private @Nullable SurfaceControlCallback mSurfaceControlCallback; /** * @inheritDoc * * @hide */ public InlineContentView(@NonNull Context context) { this(context, null); } /** * @inheritDoc * * @hide */ public InlineContentView(@NonNull Context context, @Nullable AttributeSet attrs) { this(context, attrs, 0); } /** * @inheritDoc * * @hide */ public InlineContentView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) { this(context, attrs, defStyleAttr, 0); } /** * Gets the surface control. If the surface is not created this method * returns {@code null}. * * @return The surface control. * * @see #setSurfaceControlCallback(SurfaceControlCallback) */ public @Nullable SurfaceControl getSurfaceControl() { return mSurfaceView.getSurfaceControl(); } /** * @inheritDoc * * @hide */ public class InlineContentView extends SurfaceView { public InlineContentView(@NonNull Context context, @NonNull SurfaceControlViewHost.SurfacePackage surfacePackage) { super(context); setZOrderOnTop(true); setChildSurfacePackage(surfacePackage); getHolder().setFormat(PixelFormat.TRANSPARENT); public InlineContentView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); mSurfaceView = new SurfaceView(context, attrs, defStyleAttr, defStyleRes); mSurfaceView.setZOrderOnTop(true); mSurfaceView.getHolder().setFormat(PixelFormat.TRANSPARENT); addView(mSurfaceView); } /** * Sets the embedded UI. * @param surfacePackage The embedded UI. * * @hide */ public void setChildSurfacePackage( @Nullable SurfaceControlViewHost.SurfacePackage surfacePackage) { mSurfaceView.setChildSurfacePackage(surfacePackage); } @Override public void onLayout(boolean changed, int l, int t, int r, int b) { mSurfaceView.layout(l, t, r, b); } /** * Sets a callback to observe the lifecycle of the surface control for * managing the backing surface. * * @param callback The callback to set or {@code null} to clear. */ public void setSurfaceControlCallback(@Nullable SurfaceControlCallback callback) { if (mSurfaceControlCallback != null) { mSurfaceView.getHolder().removeCallback(mSurfaceCallback); } mSurfaceControlCallback = callback; if (mSurfaceControlCallback != null) { mSurfaceView.getHolder().addCallback(mSurfaceCallback); } } /** * @return Whether the surface backing this view appears on top of its parent. * * @see #setZOrderedOnTop(boolean) */ public boolean isZOrderedOnTop() { return mSurfaceView.isZOrderedOnTop(); } /** * Controls whether the backing surface is placed on top of this view's window. * Normally, it is placed on top of the window, to allow interaction * with the inlined UI. Via this method, you can place the surface below the * window. This means that all of the contents of the window this view is in * will be visible on top of its surface. * * <p> The Z ordering can be changed dynamically if the backing surface is * created, otherwise the ordering would be applied at surface construction time. * * @param onTop Whether to show the surface on top of this view's window. * * @see #isZOrderedOnTop() */ public boolean setZOrderedOnTop(boolean onTop) { return mSurfaceView.setZOrderedOnTop(onTop, /*allowDynamicChange*/ true); } }
core/java/android/view/inputmethod/InlineSuggestion.java +12 −12 Original line number Diff line number Diff line Loading @@ -29,7 +29,6 @@ import android.os.RemoteException; import android.util.Size; import android.util.Slog; import android.view.SurfaceControlViewHost; import android.view.View; import android.view.inline.InlineContentView; import android.view.inline.InlinePresentationSpec; Loading Loading @@ -94,15 +93,15 @@ public final class InlineSuggestion implements Parcelable { this(info, contentProvider, /* inlineContentCallback */ null); } /** * Inflates a view with the content of this suggestion at a specific size. * The size must be between the {@link InlinePresentationSpec#getMinSize() min size} * and the {@link InlinePresentationSpec#getMaxSize() max size} of the presentation * spec returned by {@link InlineSuggestionInfo#getPresentationSpec()}. * * <p> The caller can attach an {@link View.OnClickListener} and/or an * {@link View.OnLongClickListener} to the view in the {@code callback} to receive click and * <p> The caller can attach an {@link android.view.View.OnClickListener} and/or an * {@link android.view.View.OnLongClickListener} to the view in the * {@code callback} to receive click and * long click events on the view. * * @param context Context in which to inflate the view. Loading @@ -113,7 +112,7 @@ public final class InlineSuggestion implements Parcelable { */ public void inflate(@NonNull Context context, @NonNull Size size, @NonNull @CallbackExecutor Executor callbackExecutor, @NonNull Consumer<View> callback) { @NonNull Consumer<InlineContentView> callback) { final Size minSize = mInfo.getPresentationSpec().getMinSize(); final Size maxSize = mInfo.getPresentationSpec().getMaxSize(); if (size.getHeight() < minSize.getHeight() || size.getHeight() > maxSize.getHeight() Loading @@ -138,7 +137,7 @@ public final class InlineSuggestion implements Parcelable { } private synchronized InlineContentCallbackImpl getInlineContentCallback(Context context, Executor callbackExecutor, Consumer<View> callback) { Executor callbackExecutor, Consumer<InlineContentView> callback) { if (mInlineContentCallback != null) { throw new IllegalStateException("Already called #inflate()"); } Loading Loading @@ -185,12 +184,12 @@ public final class InlineSuggestion implements Parcelable { private final @NonNull Context mContext; private final @NonNull Executor mCallbackExecutor; private final @NonNull Consumer<View> mCallback; private @Nullable View mView; private final @NonNull Consumer<InlineContentView> mCallback; private @Nullable InlineContentView mView; InlineContentCallbackImpl(@NonNull Context context, @NonNull @CallbackExecutor Executor callbackExecutor, @NonNull Consumer<View> callback) { @NonNull Consumer<InlineContentView> callback) { mContext = context; mCallbackExecutor = callbackExecutor; mCallback = callback; Loading @@ -201,7 +200,8 @@ public final class InlineSuggestion implements Parcelable { if (content == null) { mCallbackExecutor.execute(() -> mCallback.accept(/* view */null)); } else { mView = new InlineContentView(mContext, content); mView = new InlineContentView(mContext); mView.setChildSurfacePackage(content); mCallbackExecutor.execute(() -> mCallback.accept(mView)); } } Loading Loading @@ -398,10 +398,10 @@ public final class InlineSuggestion implements Parcelable { }; @DataClass.Generated( time = 1583889058241L, time = 1584679775946L, codegenVersion = "1.0.15", sourceFile = "frameworks/base/core/java/android/view/inputmethod/InlineSuggestion.java", inputSignatures = "private static final java.lang.String TAG\nprivate final @android.annotation.NonNull android.view.inputmethod.InlineSuggestionInfo mInfo\nprivate final @android.annotation.Nullable com.android.internal.view.inline.IInlineContentProvider mContentProvider\nprivate @com.android.internal.util.DataClass.ParcelWith(android.view.inputmethod.InlineSuggestion.InlineContentCallbackImplParceling.class) @android.annotation.Nullable android.view.inputmethod.InlineSuggestion.InlineContentCallbackImpl mInlineContentCallback\npublic static @android.annotation.TestApi @android.annotation.NonNull android.view.inputmethod.InlineSuggestion newInlineSuggestion(android.view.inputmethod.InlineSuggestionInfo)\npublic void inflate(android.content.Context,android.util.Size,java.util.concurrent.Executor,java.util.function.Consumer<android.view.View>)\nprivate synchronized android.view.inputmethod.InlineSuggestion.InlineContentCallbackImpl getInlineContentCallback(android.content.Context,java.util.concurrent.Executor,java.util.function.Consumer<android.view.View>)\nclass InlineSuggestion extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genEqualsHashCode=true, genToString=true, genHiddenConstDefs=true, genHiddenConstructor=true)") inputSignatures = "private static final java.lang.String TAG\nprivate final @android.annotation.NonNull android.view.inputmethod.InlineSuggestionInfo mInfo\nprivate final @android.annotation.Nullable com.android.internal.view.inline.IInlineContentProvider mContentProvider\nprivate @com.android.internal.util.DataClass.ParcelWith(android.view.inputmethod.InlineSuggestion.InlineContentCallbackImplParceling.class) @android.annotation.Nullable android.view.inputmethod.InlineSuggestion.InlineContentCallbackImpl mInlineContentCallback\npublic static @android.annotation.TestApi @android.annotation.NonNull android.view.inputmethod.InlineSuggestion newInlineSuggestion(android.view.inputmethod.InlineSuggestionInfo)\npublic void inflate(android.content.Context,android.util.Size,java.util.concurrent.Executor,java.util.function.Consumer<android.view.inline.InlineContentView>)\nprivate synchronized android.view.inputmethod.InlineSuggestion.InlineContentCallbackImpl getInlineContentCallback(android.content.Context,java.util.concurrent.Executor,java.util.function.Consumer<android.view.inline.InlineContentView>)\nclass InlineSuggestion extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genEqualsHashCode=true, genToString=true, genHiddenConstDefs=true, genHiddenConstructor=true)") @Deprecated private void __metadata() {} Loading