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