• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package android.view;
17 
18 import android.annotation.CallbackExecutor;
19 import android.annotation.FlaggedApi;
20 import android.annotation.NonNull;
21 import android.annotation.Nullable;
22 import android.annotation.SuppressLint;
23 import android.annotation.UiThread;
24 import android.content.Context;
25 import android.graphics.Rect;
26 import android.graphics.Region;
27 import android.hardware.HardwareBuffer;
28 import android.os.Looper;
29 import android.window.InputTransferToken;
30 import android.window.SurfaceSyncGroup;
31 
32 import com.android.window.flags.Flags;
33 
34 import java.util.concurrent.Executor;
35 
36 /**
37  * Provides an interface to the root-Surface of a View Hierarchy or Window. This
38  * is used in combination with the {@link android.view.SurfaceControl} API to enable
39  * attaching app created SurfaceControl to the SurfaceControl hierarchy used
40  * by the app, and enable SurfaceTransactions to be performed in sync with the
41  * View hierarchy drawing.
42  *
43  * This object is obtained from {@link android.view.View#getRootSurfaceControl} and
44  * {@link android.view.Window#getRootSurfaceControl}. It must be used from the UI thread of
45  * the object it was obtained from.
46  */
47 @UiThread
48 public interface AttachedSurfaceControl {
49     /**
50      * Create a transaction which will reparent {@param child} to the View hierarchy
51      * root SurfaceControl. See
52      * {@link SurfaceControl.Transaction#reparent}. This transacton must be applied
53      * or merged in to another transaction by the caller, otherwise it will have
54      * no effect.
55      *
56      * @param child The SurfaceControl to reparent.
57      * @return A new transaction which performs the reparent operation when applied.
58      */
buildReparentTransaction(@onNull SurfaceControl child)59     @Nullable SurfaceControl.Transaction buildReparentTransaction(@NonNull SurfaceControl child);
60 
61     /**
62      * Consume the passed in transaction, and request the View hierarchy to apply it atomically
63      * with the next draw. This transaction will be merged with the buffer transaction from the
64      * ViewRoot and they will show up on-screen atomically synced.
65      *
66      * This will not cause a draw to be scheduled, and if there are no other changes
67      * to the View hierarchy you may need to call {@link android.view.View#invalidate}
68      */
applyTransactionOnDraw(@onNull SurfaceControl.Transaction t)69     boolean applyTransactionOnDraw(@NonNull SurfaceControl.Transaction t);
70 
71     /**
72      * The transform hint can be used by a buffer producer to pre-rotate the rendering such that the
73      * final transformation in the system composer is identity. This can be very useful when used in
74      * conjunction with the h/w composer HAL in situations where it cannot handle rotations or
75      * handle them with an additional power cost.
76      *
77      * The transform hint should be used with ASurfaceControl APIs when submitting buffers.
78      * Example usage:
79      *
80      * 1. After a configuration change, before dequeuing a buffer, the buffer producer queries the
81      *    function for the transform hint.
82      *
83      * 2. The desired buffer width and height is rotated by the transform hint.
84      *
85      * 3. The producer dequeues a buffer of the new pre-rotated size.
86      *
87      * 4. The producer renders to the buffer such that the image is already transformed, that is
88      *    applying the transform hint to the rendering.
89      *
90      * 5. The producer applies the inverse transform hint to the buffer it just rendered.
91      *
92      * 6. The producer queues the pre-transformed buffer with the buffer transform.
93      *
94      * 7. The composer combines the buffer transform with the display transform.  If the buffer
95      *    transform happens to cancel out the display transform then no rotation is needed and there
96      *    will be no performance penalties.
97      *
98      * Note, when using ANativeWindow APIs in conjunction with a NativeActivity Surface or
99      * SurfaceView Surface, the buffer producer will already have access to the transform hint and
100      * no additional work is needed.
101      *
102      * If the root surface is not available, the API will return {@code BUFFER_TRANSFORM_IDENTITY}.
103      * The caller should register a listener to listen for any changes. @see
104      * {@link #addOnBufferTransformHintChangedListener(OnBufferTransformHintChangedListener)}.
105      * Warning: Calling this API in Android 14 (API Level 34) or earlier will crash if the root
106      * surface is not available.
107      *
108      * @see HardwareBuffer
109      */
getBufferTransformHint()110     default @SurfaceControl.BufferTransform int getBufferTransformHint() {
111         return SurfaceControl.BUFFER_TRANSFORM_IDENTITY;
112     }
113 
114     /**
115      * Buffer transform hint change listener.
116      * @see #getBufferTransformHint
117      */
118     @UiThread
119     interface OnBufferTransformHintChangedListener {
120         /**
121          * @param hint new surface transform hint
122          * @see #getBufferTransformHint
123          */
onBufferTransformHintChanged(@urfaceControl.BufferTransform int hint)124         void onBufferTransformHintChanged(@SurfaceControl.BufferTransform int hint);
125     }
126 
127     /**
128      * Registers a {@link OnBufferTransformHintChangedListener} to receive notifications about when
129      * the transform hint changes.
130      *
131      * @see #getBufferTransformHint
132      * @see #removeOnBufferTransformHintChangedListener
133      */
addOnBufferTransformHintChangedListener( @onNull OnBufferTransformHintChangedListener listener)134     default void addOnBufferTransformHintChangedListener(
135             @NonNull OnBufferTransformHintChangedListener listener) {
136     }
137 
138     /**
139      * Unregisters a {@link OnBufferTransformHintChangedListener}.
140      *
141      * @see #addOnBufferTransformHintChangedListener
142      */
removeOnBufferTransformHintChangedListener( @onNull OnBufferTransformHintChangedListener listener)143     default void removeOnBufferTransformHintChangedListener(
144             @NonNull OnBufferTransformHintChangedListener listener) {
145     }
146 
147     /**
148      * Sets the touchable region for this SurfaceControl, expressed in surface local
149      * coordinates. By default the touchable region is the entire Layer, indicating
150      * that if the layer is otherwise eligible to receive touch it receives touch
151      * on the entire surface. Setting the touchable region allows the SurfaceControl
152      * to receive touch in some regions, while allowing for pass-through in others.
153      *
154      * @param r The region to use or null to use the entire Layer bounds
155      */
setTouchableRegion(@ullable Region r)156     default void setTouchableRegion(@Nullable Region r) {
157     }
158 
159     /**
160      * Returns a SurfaceSyncGroup that can be used to sync {@link AttachedSurfaceControl} in a
161      * {@link SurfaceSyncGroup}
162      *
163      * @hide
164      */
165     @Nullable
getOrCreateSurfaceSyncGroup()166     default SurfaceSyncGroup getOrCreateSurfaceSyncGroup() {
167         return null;
168     }
169 
170     /**
171      * Set a crop region on all children parented to the layer represented by this
172      * AttachedSurfaceControl. This includes SurfaceView, and an example usage may
173      * be to ensure that SurfaceView with {@link android.view.SurfaceView#setZOrderOnTop}
174      * are cropped to a region not including the app bar.
175      * <p>
176      * This cropped is expressed in terms of insets in window-space. Negative insets
177      * are considered invalid and will produce an exception. Insets of zero will produce
178      * the same result as if this function had never been called.
179      *
180      * @param insets The insets in each direction by which to bound the children
181      *               expressed in window-space.
182      * @throws IllegalArgumentException If negative insets are provided.
183      */
setChildBoundingInsets(@onNull Rect insets)184     default void setChildBoundingInsets(@NonNull Rect insets) {
185     }
186 
187     /**
188      * Gets the token used for associating this {@link AttachedSurfaceControl} with an embedded
189      * {@link SurfaceControlViewHost} or {@link SurfaceControl}
190      *
191      * <p>This token should be passed to
192      * {@link SurfaceControlViewHost#SurfaceControlViewHost(Context, Display, InputTransferToken)}
193      * or
194      * {@link WindowManager#registerBatchedSurfaceControlInputReceiver(int, InputTransferToken,
195      * SurfaceControl, Choreographer, SurfaceControlInputReceiver)} or
196      * {@link WindowManager#registerUnbatchedSurfaceControlInputReceiver(int, InputTransferToken,
197      * SurfaceControl, Looper, SurfaceControlInputReceiver)}
198      *
199      * @return The {@link InputTransferToken} for the {@link AttachedSurfaceControl}
200      * @throws IllegalStateException if the {@link AttachedSurfaceControl} was created with no
201      * registered input
202      */
203     @NonNull
204     @FlaggedApi(Flags.FLAG_SURFACE_CONTROL_INPUT_RECEIVER)
getInputTransferToken()205     default InputTransferToken getInputTransferToken() {
206         throw new UnsupportedOperationException("The getInputTransferToken needs to be "
207                 + "implemented before making this call.");
208     }
209 
210     /**
211      * Registers a {@link OnJankDataListener} to receive jank classification data about rendered
212      * frames.
213      * <p>
214      * Use {@link SurfaceControl.OnJankDataListenerRegistration#removeAfter} to unregister the
215      * listener.
216      *
217      * @param executor The executor on which the listener will be invoked.
218      * @param listener The listener to add.
219      * @return The {@link OnJankDataListenerRegistration} for the listener.
220      */
221     @NonNull
222     @FlaggedApi(Flags.FLAG_JANK_API)
223     @SuppressLint("PairedRegistration")
registerOnJankDataListener( @onNull @allbackExecutor Executor executor, @NonNull SurfaceControl.OnJankDataListener listener)224     default SurfaceControl.OnJankDataListenerRegistration registerOnJankDataListener(
225             @NonNull @CallbackExecutor Executor executor,
226             @NonNull SurfaceControl.OnJankDataListener listener) {
227         return SurfaceControl.OnJankDataListenerRegistration.NONE;
228     }
229 }
230