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