1 /* 2 * Copyright (C) 2013 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 17 package android.view; 18 19 import static android.graphics.Matrix.MSCALE_X; 20 import static android.graphics.Matrix.MSCALE_Y; 21 import static android.graphics.Matrix.MSKEW_X; 22 import static android.graphics.Matrix.MSKEW_Y; 23 import static android.graphics.Matrix.MTRANS_X; 24 import static android.graphics.Matrix.MTRANS_Y; 25 import static android.view.SurfaceControlProto.HASH_CODE; 26 import static android.view.SurfaceControlProto.LAYER_ID; 27 import static android.view.SurfaceControlProto.NAME; 28 29 import android.Manifest; 30 import android.annotation.CallbackExecutor; 31 import android.annotation.FlaggedApi; 32 import android.annotation.FloatRange; 33 import android.annotation.IntDef; 34 import android.annotation.IntRange; 35 import android.annotation.NonNull; 36 import android.annotation.Nullable; 37 import android.annotation.RequiresPermission; 38 import android.annotation.Size; 39 import android.annotation.TestApi; 40 import android.compat.annotation.UnsupportedAppUsage; 41 import android.graphics.ColorSpace; 42 import android.graphics.GraphicBuffer; 43 import android.graphics.Matrix; 44 import android.graphics.PixelFormat; 45 import android.graphics.Point; 46 import android.graphics.Rect; 47 import android.graphics.Region; 48 import android.gui.DropInputMode; 49 import android.gui.StalledTransactionInfo; 50 import android.gui.TrustedOverlay; 51 import android.hardware.DataSpace; 52 import android.hardware.HardwareBuffer; 53 import android.hardware.OverlayProperties; 54 import android.hardware.SyncFence; 55 import android.hardware.display.DeviceProductInfo; 56 import android.hardware.display.DisplayedContentSample; 57 import android.hardware.display.DisplayedContentSamplingAttributes; 58 import android.hardware.graphics.common.DisplayDecorationSupport; 59 import android.opengl.EGLDisplay; 60 import android.opengl.EGLSync; 61 import android.os.Build; 62 import android.os.IBinder; 63 import android.os.Looper; 64 import android.os.Parcel; 65 import android.os.Parcelable; 66 import android.util.ArrayMap; 67 import android.util.Log; 68 import android.util.Slog; 69 import android.util.SparseIntArray; 70 import android.util.proto.ProtoOutputStream; 71 import android.view.Surface.OutOfResourcesException; 72 73 import com.android.internal.annotations.GuardedBy; 74 import com.android.internal.util.Preconditions; 75 import com.android.internal.util.VirtualRefBasePtr; 76 import com.android.window.flags.Flags; 77 78 import dalvik.system.CloseGuard; 79 80 import libcore.util.NativeAllocationRegistry; 81 82 import java.io.Closeable; 83 import java.lang.annotation.Retention; 84 import java.lang.annotation.RetentionPolicy; 85 import java.lang.ref.WeakReference; 86 import java.nio.ByteBuffer; 87 import java.nio.ByteOrder; 88 import java.util.ArrayList; 89 import java.util.Arrays; 90 import java.util.Objects; 91 import java.util.concurrent.Executor; 92 import java.util.function.Consumer; 93 94 /** 95 * Handle to an on-screen Surface managed by the system compositor. The SurfaceControl is 96 * a combination of a buffer source, and metadata about how to display the buffers. 97 * By constructing a {@link Surface} from this SurfaceControl you can submit buffers to be 98 * composited. Using {@link SurfaceControl.Transaction} you can manipulate various 99 * properties of how the buffer will be displayed on-screen. SurfaceControl's are 100 * arranged into a scene-graph like hierarchy, and as such any SurfaceControl may have 101 * a parent. Geometric properties like transform, crop, and Z-ordering will be inherited 102 * from the parent, as if the child were content in the parents buffer stream. 103 */ 104 public final class SurfaceControl implements Parcelable { 105 private static final String TAG = "SurfaceControl"; 106 nativeCreate(SurfaceSession session, String name, int w, int h, int format, int flags, long parentObject, Parcel metadata)107 private static native long nativeCreate(SurfaceSession session, String name, 108 int w, int h, int format, int flags, long parentObject, Parcel metadata) 109 throws OutOfResourcesException; nativeReadFromParcel(Parcel in)110 private static native long nativeReadFromParcel(Parcel in); nativeCopyFromSurfaceControl(long nativeObject)111 private static native long nativeCopyFromSurfaceControl(long nativeObject); nativeWriteToParcel(long nativeObject, Parcel out)112 private static native void nativeWriteToParcel(long nativeObject, Parcel out); nativeGetNativeSurfaceControlFinalizer()113 private static native long nativeGetNativeSurfaceControlFinalizer(); nativeDisconnect(long nativeObject)114 private static native void nativeDisconnect(long nativeObject); nativeUpdateDefaultBufferSize(long nativeObject, int width, int height)115 private static native void nativeUpdateDefaultBufferSize(long nativeObject, int width, int height); 116 nativeMirrorSurface(long mirrorOfObject)117 private static native long nativeMirrorSurface(long mirrorOfObject); nativeCreateTransaction()118 private static native long nativeCreateTransaction(); nativeGetNativeTransactionFinalizer()119 private static native long nativeGetNativeTransactionFinalizer(); nativeApplyTransaction(long transactionObj, boolean sync, boolean oneWay)120 private static native void nativeApplyTransaction(long transactionObj, boolean sync, 121 boolean oneWay); nativeMergeTransaction(long transactionObj, long otherTransactionObj)122 private static native void nativeMergeTransaction(long transactionObj, 123 long otherTransactionObj); nativeClearTransaction(long transactionObj)124 private static native void nativeClearTransaction(long transactionObj); nativeSetAnimationTransaction(long transactionObj)125 private static native void nativeSetAnimationTransaction(long transactionObj); nativeSetEarlyWakeupStart(long transactionObj)126 private static native void nativeSetEarlyWakeupStart(long transactionObj); nativeSetEarlyWakeupEnd(long transactionObj)127 private static native void nativeSetEarlyWakeupEnd(long transactionObj); nativeGetTransactionId(long transactionObj)128 private static native long nativeGetTransactionId(long transactionObj); 129 nativeSetLayer(long transactionObj, long nativeObject, int zorder)130 private static native void nativeSetLayer(long transactionObj, long nativeObject, int zorder); nativeSetRelativeLayer(long transactionObj, long nativeObject, long relativeToObject, int zorder)131 private static native void nativeSetRelativeLayer(long transactionObj, long nativeObject, 132 long relativeToObject, int zorder); nativeSetPosition(long transactionObj, long nativeObject, float x, float y)133 private static native void nativeSetPosition(long transactionObj, long nativeObject, 134 float x, float y); nativeSetScale(long transactionObj, long nativeObject, float x, float y)135 private static native void nativeSetScale(long transactionObj, long nativeObject, 136 float x, float y); nativeSetTransparentRegionHint(long transactionObj, long nativeObject, Region region)137 private static native void nativeSetTransparentRegionHint(long transactionObj, 138 long nativeObject, Region region); nativeSetAlpha(long transactionObj, long nativeObject, float alpha)139 private static native void nativeSetAlpha(long transactionObj, long nativeObject, float alpha); nativeSetMatrix(long transactionObj, long nativeObject, float dsdx, float dtdx, float dtdy, float dsdy)140 private static native void nativeSetMatrix(long transactionObj, long nativeObject, 141 float dsdx, float dtdx, 142 float dtdy, float dsdy); nativeSetColorTransform(long transactionObj, long nativeObject, float[] matrix, float[] translation)143 private static native void nativeSetColorTransform(long transactionObj, long nativeObject, 144 float[] matrix, float[] translation); nativeSetColorSpaceAgnostic(long transactionObj, long nativeObject, boolean agnostic)145 private static native void nativeSetColorSpaceAgnostic(long transactionObj, long nativeObject, 146 boolean agnostic); nativeSetGeometry(long transactionObj, long nativeObject, Rect sourceCrop, Rect dest, long orientation)147 private static native void nativeSetGeometry(long transactionObj, long nativeObject, 148 Rect sourceCrop, Rect dest, long orientation); nativeSetColor(long transactionObj, long nativeObject, float[] color)149 private static native void nativeSetColor(long transactionObj, long nativeObject, float[] color); nativeSetFlags(long transactionObj, long nativeObject, int flags, int mask)150 private static native void nativeSetFlags(long transactionObj, long nativeObject, 151 int flags, int mask); nativeSetFrameRateSelectionPriority(long transactionObj, long nativeObject, int priority)152 private static native void nativeSetFrameRateSelectionPriority(long transactionObj, 153 long nativeObject, int priority); nativeSetWindowCrop(long transactionObj, long nativeObject, int l, int t, int r, int b)154 private static native void nativeSetWindowCrop(long transactionObj, long nativeObject, 155 int l, int t, int r, int b); nativeSetCornerRadius(long transactionObj, long nativeObject, float cornerRadius)156 private static native void nativeSetCornerRadius(long transactionObj, long nativeObject, 157 float cornerRadius); nativeSetBackgroundBlurRadius(long transactionObj, long nativeObject, int blurRadius)158 private static native void nativeSetBackgroundBlurRadius(long transactionObj, long nativeObject, 159 int blurRadius); nativeSetLayerStack(long transactionObj, long nativeObject, int layerStack)160 private static native void nativeSetLayerStack(long transactionObj, long nativeObject, 161 int layerStack); nativeSetBlurRegions(long transactionObj, long nativeObj, float[][] regions, int length)162 private static native void nativeSetBlurRegions(long transactionObj, long nativeObj, 163 float[][] regions, int length); nativeSetStretchEffect(long transactionObj, long nativeObj, float width, float height, float vecX, float vecY, float maxStretchAmountX, float maxStretchAmountY, float childRelativeLeft, float childRelativeTop, float childRelativeRight, float childRelativeBottom)164 private static native void nativeSetStretchEffect(long transactionObj, long nativeObj, 165 float width, float height, float vecX, float vecY, 166 float maxStretchAmountX, float maxStretchAmountY, float childRelativeLeft, 167 float childRelativeTop, float childRelativeRight, float childRelativeBottom); nativeSetTrustedOverlay(long transactionObj, long nativeObject, int isTrustedOverlay)168 private static native void nativeSetTrustedOverlay(long transactionObj, long nativeObject, 169 int isTrustedOverlay); nativeSetDropInputMode( long transactionObj, long nativeObject, int flags)170 private static native void nativeSetDropInputMode( 171 long transactionObj, long nativeObject, int flags); nativeSetCanOccludePresentation(long transactionObj, long nativeObject, boolean canOccludePresentation)172 private static native void nativeSetCanOccludePresentation(long transactionObj, 173 long nativeObject, boolean canOccludePresentation); nativeSurfaceFlushJankData(long nativeSurfaceObject)174 private static native void nativeSurfaceFlushJankData(long nativeSurfaceObject); nativeClearContentFrameStats(long nativeObject)175 private static native boolean nativeClearContentFrameStats(long nativeObject); nativeGetContentFrameStats(long nativeObject, WindowContentFrameStats outStats)176 private static native boolean nativeGetContentFrameStats(long nativeObject, WindowContentFrameStats outStats); nativeClearAnimationFrameStats()177 private static native boolean nativeClearAnimationFrameStats(); nativeGetAnimationFrameStats(WindowAnimationFrameStats outStats)178 private static native boolean nativeGetAnimationFrameStats(WindowAnimationFrameStats outStats); 179 nativeSetDisplaySurface(long transactionObj, IBinder displayToken, long nativeSurfaceObject)180 private static native void nativeSetDisplaySurface(long transactionObj, 181 IBinder displayToken, long nativeSurfaceObject); nativeSetDisplayLayerStack(long transactionObj, IBinder displayToken, int layerStack)182 private static native void nativeSetDisplayLayerStack(long transactionObj, 183 IBinder displayToken, int layerStack); nativeSetDisplayFlags(long transactionObj, IBinder displayToken, int flags)184 private static native void nativeSetDisplayFlags(long transactionObj, 185 IBinder displayToken, int flags); nativeSetDisplayProjection(long transactionObj, IBinder displayToken, int orientation, int l, int t, int r, int b, int L, int T, int R, int B)186 private static native void nativeSetDisplayProjection(long transactionObj, 187 IBinder displayToken, int orientation, 188 int l, int t, int r, int b, 189 int L, int T, int R, int B); nativeSetDisplaySize(long transactionObj, IBinder displayToken, int width, int height)190 private static native void nativeSetDisplaySize(long transactionObj, IBinder displayToken, 191 int width, int height); nativeGetStaticDisplayInfo(long displayId)192 private static native StaticDisplayInfo nativeGetStaticDisplayInfo(long displayId); nativeGetDynamicDisplayInfo(long displayId)193 private static native DynamicDisplayInfo nativeGetDynamicDisplayInfo(long displayId); 194 private static native DisplayedContentSamplingAttributes nativeGetDisplayedContentSamplingAttributes(IBinder displayToken)195 nativeGetDisplayedContentSamplingAttributes(IBinder displayToken); nativeSetDisplayedContentSamplingEnabled(IBinder displayToken, boolean enable, int componentMask, int maxFrames)196 private static native boolean nativeSetDisplayedContentSamplingEnabled(IBinder displayToken, 197 boolean enable, int componentMask, int maxFrames); nativeGetDisplayedContentSample( IBinder displayToken, long numFrames, long timestamp)198 private static native DisplayedContentSample nativeGetDisplayedContentSample( 199 IBinder displayToken, long numFrames, long timestamp); nativeSetDesiredDisplayModeSpecs(IBinder displayToken, DesiredDisplayModeSpecs desiredDisplayModeSpecs)200 private static native boolean nativeSetDesiredDisplayModeSpecs(IBinder displayToken, 201 DesiredDisplayModeSpecs desiredDisplayModeSpecs); 202 private static native DesiredDisplayModeSpecs nativeGetDesiredDisplayModeSpecs(IBinder displayToken)203 nativeGetDesiredDisplayModeSpecs(IBinder displayToken); nativeGetDisplayNativePrimaries( IBinder displayToken)204 private static native DisplayPrimaries nativeGetDisplayNativePrimaries( 205 IBinder displayToken); nativeGetCompositionDataspaces()206 private static native int[] nativeGetCompositionDataspaces(); nativeGetOverlaySupport()207 private static native OverlayProperties nativeGetOverlaySupport(); nativeSetActiveColorMode(IBinder displayToken, int colorMode)208 private static native boolean nativeSetActiveColorMode(IBinder displayToken, 209 int colorMode); nativeGetBootDisplayModeSupport()210 private static native boolean nativeGetBootDisplayModeSupport(); nativeSetBootDisplayMode(IBinder displayToken, int displayMode)211 private static native void nativeSetBootDisplayMode(IBinder displayToken, int displayMode); nativeClearBootDisplayMode(IBinder displayToken)212 private static native void nativeClearBootDisplayMode(IBinder displayToken); nativeSetAutoLowLatencyMode(IBinder displayToken, boolean on)213 private static native void nativeSetAutoLowLatencyMode(IBinder displayToken, boolean on); nativeSetGameContentType(IBinder displayToken, boolean on)214 private static native void nativeSetGameContentType(IBinder displayToken, boolean on); nativeSetDisplayPowerMode( IBinder displayToken, int mode)215 private static native void nativeSetDisplayPowerMode( 216 IBinder displayToken, int mode); nativeReparent(long transactionObj, long nativeObject, long newParentNativeObject)217 private static native void nativeReparent(long transactionObj, long nativeObject, 218 long newParentNativeObject); nativeSetBuffer(long transactionObj, long nativeObject, HardwareBuffer buffer, long fencePtr, Consumer<SyncFence> releaseCallback)219 private static native void nativeSetBuffer(long transactionObj, long nativeObject, 220 HardwareBuffer buffer, long fencePtr, Consumer<SyncFence> releaseCallback); nativeUnsetBuffer(long transactionObj, long nativeObject)221 private static native void nativeUnsetBuffer(long transactionObj, long nativeObject); nativeSetBufferTransform(long transactionObj, long nativeObject, int transform)222 private static native void nativeSetBufferTransform(long transactionObj, long nativeObject, 223 int transform); nativeSetDataSpace(long transactionObj, long nativeObject, @DataSpace.NamedDataSpace int dataSpace)224 private static native void nativeSetDataSpace(long transactionObj, long nativeObject, 225 @DataSpace.NamedDataSpace int dataSpace); nativeSetExtendedRangeBrightness(long transactionObj, long nativeObject, float currentBufferRatio, float desiredRatio)226 private static native void nativeSetExtendedRangeBrightness(long transactionObj, 227 long nativeObject, float currentBufferRatio, float desiredRatio); nativeSetDesiredHdrHeadroom(long transactionObj, long nativeObject, float desiredRatio)228 private static native void nativeSetDesiredHdrHeadroom(long transactionObj, 229 long nativeObject, float desiredRatio); 230 nativeSetCachingHint(long transactionObj, long nativeObject, int cachingHint)231 private static native void nativeSetCachingHint(long transactionObj, 232 long nativeObject, int cachingHint); nativeSetDamageRegion(long transactionObj, long nativeObject, Region region)233 private static native void nativeSetDamageRegion(long transactionObj, long nativeObject, 234 Region region); nativeSetDimmingEnabled(long transactionObj, long nativeObject, boolean dimmingEnabled)235 private static native void nativeSetDimmingEnabled(long transactionObj, long nativeObject, 236 boolean dimmingEnabled); 237 nativeSetInputWindowInfo(long transactionObj, long nativeObject, InputWindowHandle handle)238 private static native void nativeSetInputWindowInfo(long transactionObj, long nativeObject, 239 InputWindowHandle handle); 240 nativeGetProtectedContentSupport()241 private static native boolean nativeGetProtectedContentSupport(); nativeSetMetadata(long transactionObj, long nativeObject, int key, Parcel data)242 private static native void nativeSetMetadata(long transactionObj, long nativeObject, int key, 243 Parcel data); nativeAddWindowInfosReportedListener(long transactionObj, Runnable listener)244 private static native void nativeAddWindowInfosReportedListener(long transactionObj, 245 Runnable listener); nativeGetDisplayBrightnessSupport(IBinder displayToken)246 private static native boolean nativeGetDisplayBrightnessSupport(IBinder displayToken); nativeSetDisplayBrightness(IBinder displayToken, float sdrBrightness, float sdrBrightnessNits, float displayBrightness, float displayBrightnessNits)247 private static native boolean nativeSetDisplayBrightness(IBinder displayToken, 248 float sdrBrightness, float sdrBrightnessNits, float displayBrightness, 249 float displayBrightnessNits); nativeReadTransactionFromParcel(Parcel in)250 private static native long nativeReadTransactionFromParcel(Parcel in); nativeWriteTransactionToParcel(long nativeObject, Parcel out)251 private static native void nativeWriteTransactionToParcel(long nativeObject, Parcel out); nativeSetShadowRadius(long transactionObj, long nativeObject, float shadowRadius)252 private static native void nativeSetShadowRadius(long transactionObj, long nativeObject, 253 float shadowRadius); nativeSetGlobalShadowSettings(@ize4) float[] ambientColor, @Size(4) float[] spotColor, float lightPosY, float lightPosZ, float lightRadius)254 private static native void nativeSetGlobalShadowSettings(@Size(4) float[] ambientColor, 255 @Size(4) float[] spotColor, float lightPosY, float lightPosZ, float lightRadius); nativeGetDisplayDecorationSupport( IBinder displayToken)256 private static native DisplayDecorationSupport nativeGetDisplayDecorationSupport( 257 IBinder displayToken); 258 nativeSetFrameRate(long transactionObj, long nativeObject, float frameRate, int compatibility, int changeFrameRateStrategy)259 private static native void nativeSetFrameRate(long transactionObj, long nativeObject, 260 float frameRate, int compatibility, int changeFrameRateStrategy); nativeSetDefaultFrameRateCompatibility(long transactionObj, long nativeObject, int compatibility)261 private static native void nativeSetDefaultFrameRateCompatibility(long transactionObj, 262 long nativeObject, int compatibility); nativeSetFrameRateCategory( long transactionObj, long nativeObject, int category, boolean smoothSwitchOnly)263 private static native void nativeSetFrameRateCategory( 264 long transactionObj, long nativeObject, int category, boolean smoothSwitchOnly); nativeSetFrameRateSelectionStrategy( long transactionObj, long nativeObject, int strategy)265 private static native void nativeSetFrameRateSelectionStrategy( 266 long transactionObj, long nativeObject, int strategy); nativeGetHandle(long nativeObject)267 private static native long nativeGetHandle(long nativeObject); 268 nativeSetFixedTransformHint(long transactionObj, long nativeObject, int transformHint)269 private static native void nativeSetFixedTransformHint(long transactionObj, long nativeObject, 270 int transformHint); nativeRemoveCurrentInputFocus(long nativeObject, int displayId)271 private static native void nativeRemoveCurrentInputFocus(long nativeObject, int displayId); nativeSetFocusedWindow(long transactionObj, IBinder toToken, String windowName, int displayId)272 private static native void nativeSetFocusedWindow(long transactionObj, IBinder toToken, 273 String windowName, int displayId); nativeSetFrameTimelineVsync(long transactionObj, long frameTimelineVsyncId)274 private static native void nativeSetFrameTimelineVsync(long transactionObj, 275 long frameTimelineVsyncId); nativeAddJankDataListener(long nativeListener, long nativeSurfaceControl)276 private static native void nativeAddJankDataListener(long nativeListener, 277 long nativeSurfaceControl); nativeRemoveJankDataListener(long nativeListener)278 private static native void nativeRemoveJankDataListener(long nativeListener); nativeCreateJankDataListenerWrapper(OnJankDataListener listener)279 private static native long nativeCreateJankDataListenerWrapper(OnJankDataListener listener); nativeGetGPUContextPriority()280 private static native int nativeGetGPUContextPriority(); nativeSetTransformHint(long nativeObject, @SurfaceControl.BufferTransform int transformHint)281 private static native void nativeSetTransformHint(long nativeObject, 282 @SurfaceControl.BufferTransform int transformHint); nativeGetTransformHint(long nativeObject)283 private static native int nativeGetTransformHint(long nativeObject); nativeGetLayerId(long nativeObject)284 private static native int nativeGetLayerId(long nativeObject); nativeAddTransactionCommittedListener(long nativeObject, TransactionCommittedListener listener)285 private static native void nativeAddTransactionCommittedListener(long nativeObject, 286 TransactionCommittedListener listener); nativeAddTransactionCompletedListener(long nativeObject, Consumer<TransactionStats> listener)287 private static native void nativeAddTransactionCompletedListener(long nativeObject, 288 Consumer<TransactionStats> listener); nativeSanitize(long transactionObject, int pid, int uid)289 private static native void nativeSanitize(long transactionObject, int pid, int uid); nativeSetDestinationFrame(long transactionObj, long nativeObject, int l, int t, int r, int b)290 private static native void nativeSetDestinationFrame(long transactionObj, long nativeObject, 291 int l, int t, int r, int b); nativeSetDefaultApplyToken(IBinder token)292 private static native void nativeSetDefaultApplyToken(IBinder token); nativeGetDefaultApplyToken()293 private static native IBinder nativeGetDefaultApplyToken(); nativeBootFinished()294 private static native boolean nativeBootFinished(); nativeCreateTpc(TrustedPresentationCallback callback)295 private static native long nativeCreateTpc(TrustedPresentationCallback callback); getNativeTrustedPresentationCallbackFinalizer()296 private static native long getNativeTrustedPresentationCallbackFinalizer(); nativeSetTrustedPresentationCallback(long transactionObj, long nativeObject, long nativeTpc, TrustedPresentationThresholds thresholds)297 private static native void nativeSetTrustedPresentationCallback(long transactionObj, 298 long nativeObject, long nativeTpc, TrustedPresentationThresholds thresholds); nativeClearTrustedPresentationCallback(long transactionObj, long nativeObject)299 private static native void nativeClearTrustedPresentationCallback(long transactionObj, 300 long nativeObject); nativeGetStalledTransactionInfo(int pid)301 private static native StalledTransactionInfo nativeGetStalledTransactionInfo(int pid); nativeSetDesiredPresentTimeNanos(long transactionObj, long desiredPresentTimeNanos)302 private static native void nativeSetDesiredPresentTimeNanos(long transactionObj, 303 long desiredPresentTimeNanos); nativeSetFrameTimeline(long transactionObj, long vsyncId)304 private static native void nativeSetFrameTimeline(long transactionObj, 305 long vsyncId); nativeNotifyShutdown()306 private static native void nativeNotifyShutdown(); 307 308 /** 309 * Transforms that can be applied to buffers as they are displayed to a window. 310 * 311 * Supported transforms are any combination of horizontal mirror, vertical mirror, and 312 * clock-wise 90 degree rotation, in that order. Rotations of 180 and 270 degrees are made up 313 * of those basic transforms. 314 * Mirrors {@code ANativeWindowTransform} definitions. 315 * @hide 316 */ 317 @Retention(RetentionPolicy.SOURCE) 318 @IntDef(prefix = {"BUFFER_TRANSFORM_"}, 319 value = {BUFFER_TRANSFORM_IDENTITY, BUFFER_TRANSFORM_MIRROR_HORIZONTAL, 320 BUFFER_TRANSFORM_MIRROR_VERTICAL, BUFFER_TRANSFORM_ROTATE_90, 321 BUFFER_TRANSFORM_ROTATE_180, BUFFER_TRANSFORM_ROTATE_270, 322 BUFFER_TRANSFORM_MIRROR_HORIZONTAL | BUFFER_TRANSFORM_ROTATE_90, 323 BUFFER_TRANSFORM_MIRROR_VERTICAL | BUFFER_TRANSFORM_ROTATE_90}) 324 public @interface BufferTransform { 325 } 326 327 /** 328 * Identity transform. 329 * 330 * These transforms that can be applied to buffers as they are displayed to a window. 331 * @see HardwareBuffer 332 * 333 * Supported transforms are any combination of horizontal mirror, vertical mirror, and 334 * clock-wise 90 degree rotation, in that order. Rotations of 180 and 270 degrees are 335 * made up of those basic transforms. 336 */ 337 public static final int BUFFER_TRANSFORM_IDENTITY = 0x00; 338 /** 339 * Mirror horizontally. Can be combined with {@link #BUFFER_TRANSFORM_MIRROR_VERTICAL} 340 * and {@link #BUFFER_TRANSFORM_ROTATE_90}. 341 */ 342 public static final int BUFFER_TRANSFORM_MIRROR_HORIZONTAL = 0x01; 343 /** 344 * Mirror vertically. Can be combined with {@link #BUFFER_TRANSFORM_MIRROR_HORIZONTAL} 345 * and {@link #BUFFER_TRANSFORM_ROTATE_90}. 346 */ 347 public static final int BUFFER_TRANSFORM_MIRROR_VERTICAL = 0x02; 348 /** 349 * Rotate 90 degrees clock-wise. Can be combined with {@link 350 * #BUFFER_TRANSFORM_MIRROR_HORIZONTAL} and {@link #BUFFER_TRANSFORM_MIRROR_VERTICAL}. 351 */ 352 public static final int BUFFER_TRANSFORM_ROTATE_90 = 0x04; 353 /** 354 * Rotate 180 degrees clock-wise. Cannot be combined with other transforms. 355 */ 356 public static final int BUFFER_TRANSFORM_ROTATE_180 = 357 BUFFER_TRANSFORM_MIRROR_HORIZONTAL | BUFFER_TRANSFORM_MIRROR_VERTICAL; 358 /** 359 * Rotate 270 degrees clock-wise. Cannot be combined with other transforms. 360 */ 361 public static final int BUFFER_TRANSFORM_ROTATE_270 = 362 BUFFER_TRANSFORM_ROTATE_180 | BUFFER_TRANSFORM_ROTATE_90; 363 364 /** 365 * @hide 366 */ rotationToBufferTransform(@urface.Rotation int rotation)367 public static @BufferTransform int rotationToBufferTransform(@Surface.Rotation int rotation) { 368 switch (rotation) { 369 case Surface.ROTATION_0: return BUFFER_TRANSFORM_IDENTITY; 370 case Surface.ROTATION_90: return BUFFER_TRANSFORM_ROTATE_90; 371 case Surface.ROTATION_180: return BUFFER_TRANSFORM_ROTATE_180; 372 case Surface.ROTATION_270: return BUFFER_TRANSFORM_ROTATE_270; 373 } 374 Log.e(TAG, "Trying to convert unknown rotation=" + rotation); 375 return BUFFER_TRANSFORM_IDENTITY; 376 } 377 378 @Nullable 379 @GuardedBy("mLock") 380 private ArrayList<OnReparentListener> mReparentListeners; 381 382 /** 383 * Listener to observe surface reparenting. 384 * 385 * @hide 386 */ 387 public interface OnReparentListener { 388 389 /** 390 * Callback for reparenting surfaces. 391 * 392 * Important: You should only interact with the provided surface control 393 * only if you have a contract with its owner to avoid them closing it 394 * under you or vise versa. 395 * 396 * @param transaction The transaction that would commit reparenting. 397 * @param parent The future parent surface. 398 */ onReparent(@onNull Transaction transaction, @Nullable SurfaceControl parent)399 void onReparent(@NonNull Transaction transaction, @Nullable SurfaceControl parent); 400 } 401 402 /** 403 * Jank information to be fed back via {@link OnJankDataListener}. 404 * @hide 405 */ 406 public static class JankData { 407 408 /** @hide */ 409 @IntDef(flag = true, value = {JANK_NONE, 410 DISPLAY_HAL, 411 JANK_SURFACEFLINGER_DEADLINE_MISSED, 412 JANK_SURFACEFLINGER_GPU_DEADLINE_MISSED, 413 JANK_APP_DEADLINE_MISSED, 414 PREDICTION_ERROR, 415 SURFACE_FLINGER_SCHEDULING}) 416 @Retention(RetentionPolicy.SOURCE) 417 public @interface JankType {} 418 419 // Needs to be kept in sync with frameworks/native/libs/gui/include/gui/JankInfo.h 420 421 // No Jank 422 public static final int JANK_NONE = 0x0; 423 424 // Jank not related to SurfaceFlinger or the App 425 public static final int DISPLAY_HAL = 0x1; 426 // SF took too long on the CPU 427 public static final int JANK_SURFACEFLINGER_DEADLINE_MISSED = 0x2; 428 // SF took too long on the GPU 429 public static final int JANK_SURFACEFLINGER_GPU_DEADLINE_MISSED = 0x4; 430 // Either App or GPU took too long on the frame 431 public static final int JANK_APP_DEADLINE_MISSED = 0x8; 432 // Vsync predictions have drifted beyond the threshold from the actual HWVsync 433 public static final int PREDICTION_ERROR = 0x10; 434 // Latching a buffer early might cause an early present of the frame 435 public static final int SURFACE_FLINGER_SCHEDULING = 0x20; 436 // A buffer is said to be stuffed if it was expected to be presented on a vsync but was 437 // presented later because the previous buffer was presented in its expected vsync. This 438 // usually happens if there is an unexpectedly long frame causing the rest of the buffers 439 // to enter a stuffed state. 440 public static final int BUFFER_STUFFING = 0x40; 441 // Jank due to unknown reasons. 442 public static final int UNKNOWN = 0x80; 443 JankData(long frameVsyncId, @JankType int jankType, long frameIntervalNs)444 public JankData(long frameVsyncId, @JankType int jankType, long frameIntervalNs) { 445 this.frameVsyncId = frameVsyncId; 446 this.jankType = jankType; 447 this.frameIntervalNs = frameIntervalNs; 448 449 } 450 451 public final long frameVsyncId; 452 public final @JankType int jankType; 453 public final long frameIntervalNs; 454 } 455 456 /** 457 * Listener interface to be informed about SurfaceFlinger's jank classification for a specific 458 * surface. 459 * 460 * @see JankData 461 * @see #addJankDataListener 462 * @hide 463 */ 464 public static abstract class OnJankDataListener { 465 private final VirtualRefBasePtr mNativePtr; 466 OnJankDataListener()467 public OnJankDataListener() { 468 mNativePtr = new VirtualRefBasePtr(nativeCreateJankDataListenerWrapper(this)); 469 } 470 471 /** 472 * Called when new jank classifications are available. 473 */ onJankDataAvailable(JankData[] jankStats)474 public abstract void onJankDataAvailable(JankData[] jankStats); 475 } 476 477 private final CloseGuard mCloseGuard = CloseGuard.get(); 478 private String mName; 479 private String mCallsite; 480 481 /** 482 * Note: do not rename, this field is used by native code. 483 * @hide 484 */ 485 public long mNativeObject; 486 private long mNativeHandle; 487 488 private final Object mChoreographerLock = new Object(); 489 @GuardedBy("mChoreographerLock") 490 private Choreographer mChoreographer; 491 492 // TODO: Move width/height to native and fix locking through out. 493 private final Object mLock = new Object(); 494 @GuardedBy("mLock") 495 private int mWidth; 496 @GuardedBy("mLock") 497 private int mHeight; 498 499 private TrustedPresentationCallback mTrustedPresentationCallback; 500 501 private WeakReference<View> mLocalOwnerView; 502 503 // A throwable with the stack filled when this SurfaceControl is released (only if 504 // sDebugUsageAfterRelease) is enabled 505 private Throwable mReleaseStack = null; 506 507 // Triggers the stack to be saved when any SurfaceControl in this process is released, which can 508 // be dumped as additional context 509 private static volatile boolean sDebugUsageAfterRelease = false; 510 511 private static final NativeAllocationRegistry sRegistry = 512 NativeAllocationRegistry.createMalloced(SurfaceControl.class.getClassLoader(), 513 nativeGetNativeSurfaceControlFinalizer()); 514 515 private Runnable mFreeNativeResources; 516 517 /** 518 * Adds a reparenting listener. 519 * 520 * @param listener The listener. 521 * @return Whether listener was added. 522 * 523 * @hide 524 */ addOnReparentListener(@onNull OnReparentListener listener)525 public boolean addOnReparentListener(@NonNull OnReparentListener listener) { 526 synchronized (mLock) { 527 if (mReparentListeners == null) { 528 mReparentListeners = new ArrayList<>(1); 529 } 530 return mReparentListeners.add(listener); 531 } 532 } 533 534 /** 535 * Removes a reparenting listener. 536 * 537 * @param listener The listener. 538 * @return Whether listener was removed. 539 * 540 * @hide 541 */ removeOnReparentListener(@onNull OnReparentListener listener)542 public boolean removeOnReparentListener(@NonNull OnReparentListener listener) { 543 synchronized (mLock) { 544 final boolean removed = mReparentListeners.remove(listener); 545 if (mReparentListeners.isEmpty()) { 546 mReparentListeners = null; 547 } 548 return removed; 549 } 550 } 551 552 /* flags used in constructor (keep in sync with ISurfaceComposerClient.h) */ 553 554 /** 555 * Surface creation flag: Surface is created hidden 556 * @hide 557 */ 558 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) 559 public static final int HIDDEN = 0x00000004; 560 561 /** 562 * Surface creation flag: Skip this layer and its children when taking a screenshot. This 563 * also includes mirroring and screen recording, so the layers with flag SKIP_SCREENSHOT 564 * will not be included on non primary displays. 565 * @hide 566 */ 567 public static final int SKIP_SCREENSHOT = 0x00000040; 568 569 /** 570 * Surface creation flag: Special measures will be taken to disallow the surface's content to 571 * be copied. In particular, screenshots and secondary, non-secure displays will render black 572 * content instead of the surface content. 573 * 574 * @see com.android.server.display.DisplayControl#createDisplay(String, boolean) 575 * @hide 576 */ 577 public static final int SECURE = 0x00000080; 578 579 580 /** 581 * Queue up BufferStateLayer buffers instead of dropping the oldest buffer when this flag is 582 * set. This blocks the client until all the buffers have been presented. If the buffers 583 * have presentation timestamps, then we may drop buffers. 584 * @hide 585 */ 586 public static final int ENABLE_BACKPRESSURE = 0x00000100; 587 588 /** 589 * Buffers from this SurfaceControl should be considered display decorations. 590 * 591 * If the hardware has optimizations for display decorations (e.g. rounded corners, camera 592 * cutouts, etc), it should use them for this layer. 593 * @hide 594 */ 595 public static final int DISPLAY_DECORATION = 0x00000200; 596 597 /** 598 * Ignore any destination frame set on the layer. This is used when the buffer scaling mode 599 * is freeze and the destination frame is applied asynchronously with the buffer submission. 600 * This is needed to maintain compatibility for SurfaceView scaling behavior. 601 * See SurfaceView scaling behavior for more details. 602 * @hide 603 */ 604 public static final int IGNORE_DESTINATION_FRAME = 0x00000400; 605 606 /** 607 * Special casing for layer that is a refresh rate indicator 608 * @hide 609 */ 610 public static final int LAYER_IS_REFRESH_RATE_INDICATOR = 0x00000800; 611 612 /** 613 * Sets a property on this layer indicating that its visible region should be considered when 614 * computing TrustedPresentation Thresholds 615 * @hide 616 */ 617 public static final int CAN_OCCLUDE_PRESENTATION = 0x00001000; 618 619 /** 620 * Surface creation flag: Creates a surface where color components are interpreted 621 * as "non pre-multiplied" by their alpha channel. Of course this flag is 622 * meaningless for surfaces without an alpha channel. By default 623 * surfaces are pre-multiplied, which means that each color component is 624 * already multiplied by its alpha value. In this case the blending 625 * equation used is: 626 * <p> 627 * <code>DEST = SRC + DEST * (1-SRC_ALPHA)</code> 628 * <p> 629 * By contrast, non pre-multiplied surfaces use the following equation: 630 * <p> 631 * <code>DEST = SRC * SRC_ALPHA * DEST * (1-SRC_ALPHA)</code> 632 * <p> 633 * pre-multiplied surfaces must always be used if transparent pixels are 634 * composited on top of each-other into the surface. A pre-multiplied 635 * surface can never lower the value of the alpha component of a given 636 * pixel. 637 * <p> 638 * In some rare situations, a non pre-multiplied surface is preferable. 639 * @hide 640 */ 641 public static final int NON_PREMULTIPLIED = 0x00000100; 642 643 /** 644 * Surface creation flag: Indicates that the surface must be considered opaque, 645 * even if its pixel format contains an alpha channel. This can be useful if an 646 * application needs full RGBA 8888 support for instance but will 647 * still draw every pixel opaque. 648 * <p> 649 * This flag is ignored if setAlpha() is used to make the surface non-opaque. 650 * Combined effects are (assuming a buffer format with an alpha channel): 651 * <ul> 652 * <li>OPAQUE + alpha(1.0) == opaque composition 653 * <li>OPAQUE + alpha(0.x) == blended composition 654 * <li>!OPAQUE + alpha(1.0) == blended composition 655 * <li>!OPAQUE + alpha(0.x) == blended composition 656 * </ul> 657 * If the underlying buffer lacks an alpha channel, the OPAQUE flag is effectively 658 * set automatically. 659 * @hide 660 */ 661 public static final int OPAQUE = 0x00000400; 662 663 /** 664 * Surface creation flag: Application requires a hardware-protected path to an 665 * external display sink. If a hardware-protected path is not available, 666 * then this surface will not be displayed on the external sink. 667 * 668 * @hide 669 */ 670 public static final int PROTECTED_APP = 0x00000800; 671 672 // 0x1000 is reserved for an independent DRM protected flag in framework 673 674 /** 675 * Surface creation flag: Window represents a cursor glyph. 676 * @hide 677 */ 678 public static final int CURSOR_WINDOW = 0x00002000; 679 680 /** 681 * Surface creation flag: Indicates the effect layer will not have a color fill on 682 * creation. 683 * 684 * @hide 685 */ 686 public static final int NO_COLOR_FILL = 0x00004000; 687 688 /** 689 * Surface creation flag: Creates a normal surface. 690 * This is the default. 691 * 692 * @hide 693 */ 694 public static final int FX_SURFACE_NORMAL = 0x00000000; 695 696 /** 697 * Surface creation flag: Creates a effect surface which 698 * represents a solid color and or shadows. 699 * 700 * @hide 701 */ 702 public static final int FX_SURFACE_EFFECT = 0x00020000; 703 704 /** 705 * Surface creation flag: Creates a container surface. 706 * This surface will have no buffers and will only be used 707 * as a container for other surfaces, or for its InputInfo. 708 * @hide 709 */ 710 public static final int FX_SURFACE_CONTAINER = 0x00080000; 711 712 /** 713 * @hide 714 */ 715 public static final int FX_SURFACE_BLAST = 0x00040000; 716 717 /** 718 * Mask used for FX values above. 719 * 720 * @hide 721 */ 722 public static final int FX_SURFACE_MASK = 0x000F0000; 723 724 /* flags used with setFlags() (keep in sync with ISurfaceComposer.h) */ 725 726 /** 727 * Surface flag: Hide the surface. 728 * Equivalent to calling hide(). 729 * Updates the value set during Surface creation (see {@link #HIDDEN}). 730 */ 731 private static final int SURFACE_HIDDEN = 0x01; 732 733 /** 734 * Surface flag: composite without blending when possible. 735 * Updates the value set during Surface creation (see {@link #OPAQUE}). 736 */ 737 private static final int SURFACE_OPAQUE = 0x02; 738 739 /* flags used with setDisplayFlags() (keep in sync with DisplayDevice.h) */ 740 741 /** 742 * DisplayDevice flag: This display's transform is sent to inputflinger and used for input 743 * dispatch. This flag is used to disambiguate displays which share a layerstack. 744 * @hide 745 */ 746 public static final int DISPLAY_RECEIVES_INPUT = 0x01; 747 748 // Display power modes. 749 /** 750 * Display power mode off: used while blanking the screen. 751 * Use only with {@link SurfaceControl#setDisplayPowerMode}. 752 * @hide 753 */ 754 public static final int POWER_MODE_OFF = 0; 755 756 /** 757 * Display power mode doze: used while putting the screen into low power mode. 758 * Use only with {@link SurfaceControl#setDisplayPowerMode}. 759 * @hide 760 */ 761 public static final int POWER_MODE_DOZE = 1; 762 763 /** 764 * Display power mode normal: used while unblanking the screen. 765 * Use only with {@link SurfaceControl#setDisplayPowerMode}. 766 * @hide 767 */ 768 public static final int POWER_MODE_NORMAL = 2; 769 770 /** 771 * Display power mode doze: used while putting the screen into a suspended 772 * low power mode. Use only with {@link SurfaceControl#setDisplayPowerMode}. 773 * @hide 774 */ 775 public static final int POWER_MODE_DOZE_SUSPEND = 3; 776 777 /** 778 * Display power mode on: used while putting the screen into a suspended 779 * full power mode. Use only with {@link SurfaceControl#setDisplayPowerMode}. 780 * @hide 781 */ 782 public static final int POWER_MODE_ON_SUSPEND = 4; 783 784 /** 785 * Hint that this SurfaceControl should not participate in layer caching within SurfaceFlinger. 786 * 787 * A system layer may request that a layer does not participate in caching when there are known 788 * quality limitations when caching via the compositor's GPU path. 789 * Use only with {@link SurfaceControl.Transaction#setCachingHint}. 790 * @hide 791 */ 792 public static final int CACHING_DISABLED = 0; 793 794 /** 795 * Hint that this SurfaceControl should participate in layer caching within SurfaceFlinger. 796 * 797 * Use only with {@link SurfaceControl.Transaction#setCachingHint}. 798 * @hide 799 */ 800 public static final int CACHING_ENABLED = 1; 801 802 /** @hide */ 803 @IntDef(flag = true, value = {CACHING_DISABLED, CACHING_ENABLED}) 804 @Retention(RetentionPolicy.SOURCE) 805 public @interface CachingHint {} 806 assignNativeObject(long nativeObject, String callsite)807 private void assignNativeObject(long nativeObject, String callsite) { 808 if (mNativeObject != 0) { 809 release(); 810 } 811 if (nativeObject != 0) { 812 mFreeNativeResources = 813 sRegistry.registerNativeAllocation(this, nativeObject); 814 } 815 mNativeObject = nativeObject; 816 mNativeHandle = mNativeObject != 0 ? nativeGetHandle(nativeObject) : 0; 817 if (sDebugUsageAfterRelease && mNativeObject == 0) { 818 mReleaseStack = new Throwable("Assigned invalid nativeObject"); 819 } else { 820 mReleaseStack = null; 821 } 822 setUnreleasedWarningCallSite(callsite); 823 if (nativeObject != 0) { 824 // Only add valid surface controls to the registry. This is called at the end of this 825 // method since its information is dumped if the process threshold is reached. 826 SurfaceControlRegistry.getProcessInstance().add(this); 827 } 828 } 829 830 /** 831 * @hide 832 */ copyFrom(@onNull SurfaceControl other, String callsite)833 public void copyFrom(@NonNull SurfaceControl other, String callsite) { 834 mName = other.mName; 835 mWidth = other.mWidth; 836 mHeight = other.mHeight; 837 mLocalOwnerView = other.mLocalOwnerView; 838 assignNativeObject(nativeCopyFromSurfaceControl(other.mNativeObject), callsite); 839 } 840 841 /** 842 * owner UID. 843 * @hide 844 */ 845 public static final int METADATA_OWNER_UID = 1; 846 847 /** 848 * Window type as per {@link WindowManager.LayoutParams}. 849 * @hide 850 */ 851 public static final int METADATA_WINDOW_TYPE = 2; 852 853 /** 854 * Task id to allow association between surfaces and task. 855 * @hide 856 */ 857 public static final int METADATA_TASK_ID = 3; 858 859 /** 860 * The style of mouse cursor and hotspot. 861 * @hide 862 */ 863 public static final int METADATA_MOUSE_CURSOR = 4; 864 865 /** 866 * Accessibility ID to allow association between surfaces and accessibility tree. 867 * @hide 868 */ 869 public static final int METADATA_ACCESSIBILITY_ID = 5; 870 871 /** 872 * owner PID. 873 * @hide 874 */ 875 public static final int METADATA_OWNER_PID = 6; 876 877 /** 878 * game mode for the layer - used for metrics 879 * @hide 880 */ 881 public static final int METADATA_GAME_MODE = 8; 882 883 /** @hide */ 884 @Retention(RetentionPolicy.SOURCE) 885 @IntDef(prefix = {"FRAME_RATE_SELECTION_STRATEGY_"}, 886 value = {FRAME_RATE_SELECTION_STRATEGY_PROPAGATE, 887 FRAME_RATE_SELECTION_STRATEGY_OVERRIDE_CHILDREN, 888 FRAME_RATE_SELECTION_STRATEGY_SELF}) 889 public @interface FrameRateSelectionStrategy {} 890 891 // From window.h. Keep these in sync. 892 /** 893 * Default value. The layer uses its own frame rate specifications, assuming it has any 894 * specifications, instead of its parent's. If it does not have its own frame rate 895 * specifications, it will try to use its parent's. It will propagate its specifications to any 896 * descendants that do not have their own. 897 * 898 * However, {@link #FRAME_RATE_SELECTION_STRATEGY_OVERRIDE_CHILDREN} on an ancestor layer 899 * supersedes this behavior, meaning that this layer will inherit frame rate specifications 900 * regardless of whether it has its own. 901 * @hide 902 */ 903 public static final int FRAME_RATE_SELECTION_STRATEGY_PROPAGATE = 0; 904 905 /** 906 * The layer's frame rate specifications will propagate to and override those of its descendant 907 * layers. 908 * 909 * The layer itself has the {@link #FRAME_RATE_SELECTION_STRATEGY_PROPAGATE} behavior. 910 * Thus, ancestor layer that also has the strategy 911 * {@link #FRAME_RATE_SELECTION_STRATEGY_OVERRIDE_CHILDREN} will override this layer's 912 * frame rate specifications. 913 * @hide 914 */ 915 public static final int FRAME_RATE_SELECTION_STRATEGY_OVERRIDE_CHILDREN = 1; 916 917 /** 918 * The layer's frame rate specifications will not propagate to its descendant 919 * layers, even if the descendant layer has no frame rate specifications. 920 * However, {@link #FRAME_RATE_SELECTION_STRATEGY_OVERRIDE_CHILDREN} on an ancestor 921 * layer supersedes this behavior. 922 * @hide 923 */ 924 public static final int FRAME_RATE_SELECTION_STRATEGY_SELF = 2; 925 926 /** 927 * Builder class for {@link SurfaceControl} objects. 928 * 929 * By default the surface will be hidden, and have "unset" bounds, meaning it can 930 * be as large as the bounds of its parent if a buffer or child so requires. 931 * 932 * It is necessary to set at least a name via {@link Builder#setName} 933 */ 934 public static class Builder { 935 private SurfaceSession mSession; 936 private int mFlags = HIDDEN; 937 private int mWidth; 938 private int mHeight; 939 private int mFormat = PixelFormat.OPAQUE; 940 private String mName; 941 private WeakReference<View> mLocalOwnerView; 942 private SurfaceControl mParent; 943 private SparseIntArray mMetadata; 944 private String mCallsite = "SurfaceControl.Builder"; 945 946 /** 947 * Begin building a SurfaceControl with a given {@link SurfaceSession}. 948 * 949 * @param session The {@link SurfaceSession} with which to eventually construct the surface. 950 * @hide 951 */ Builder(SurfaceSession session)952 public Builder(SurfaceSession session) { 953 mSession = session; 954 } 955 956 /** 957 * Begin building a SurfaceControl. 958 */ Builder()959 public Builder() { 960 } 961 962 /** 963 * Construct a new {@link SurfaceControl} with the set parameters. The builder 964 * remains valid. 965 */ 966 @NonNull build()967 public SurfaceControl build() { 968 if (mWidth < 0 || mHeight < 0) { 969 throw new IllegalStateException( 970 "width and height must be positive or unset"); 971 } 972 if ((mWidth > 0 || mHeight > 0) && (isEffectLayer() || isContainerLayer())) { 973 throw new IllegalStateException( 974 "Only buffer layers can set a valid buffer size."); 975 } 976 977 if (mName == null) { 978 Log.w(TAG, "Missing name for SurfaceControl", new Throwable()); 979 } 980 981 if ((mFlags & FX_SURFACE_MASK) == FX_SURFACE_NORMAL) { 982 setBLASTLayer(); 983 } 984 985 return new SurfaceControl( 986 mSession, mName, mWidth, mHeight, mFormat, mFlags, mParent, mMetadata, 987 mLocalOwnerView, mCallsite); 988 } 989 990 /** 991 * Set a debugging-name for the SurfaceControl. 992 * 993 * @param name A name to identify the Surface in debugging. 994 */ 995 @NonNull setName(@onNull String name)996 public Builder setName(@NonNull String name) { 997 mName = name; 998 return this; 999 } 1000 1001 /** 1002 * Set the local owner view for the surface. This view is only 1003 * valid in the same process and is not transferred in an IPC. 1004 * 1005 * Note: This is used for cases where we want to know the view 1006 * that manages the surface control while intercepting reparenting. 1007 * A specific example is InlineContentView which exposes is surface 1008 * control for reparenting as a way to implement clipping of several 1009 * InlineContentView instances within a certain area. 1010 * 1011 * @param view The owner view. 1012 * @return This builder. 1013 * 1014 * @hide 1015 */ 1016 @NonNull setLocalOwnerView(@onNull View view)1017 public Builder setLocalOwnerView(@NonNull View view) { 1018 mLocalOwnerView = new WeakReference<>(view); 1019 return this; 1020 } 1021 1022 /** 1023 * Set the initial size of the controlled surface's buffers in pixels. 1024 * 1025 * @param width The buffer width in pixels. 1026 * @param height The buffer height in pixels. 1027 */ 1028 @NonNull setBufferSize(@ntRangefrom = 0) int width, @IntRange(from = 0) int height)1029 public Builder setBufferSize(@IntRange(from = 0) int width, 1030 @IntRange(from = 0) int height) { 1031 if (width < 0 || height < 0) { 1032 throw new IllegalArgumentException( 1033 "width and height must be positive"); 1034 } 1035 mWidth = width; 1036 mHeight = height; 1037 // set this as a buffer layer since we are specifying a buffer size. 1038 return setFlags(FX_SURFACE_NORMAL, FX_SURFACE_MASK); 1039 } 1040 unsetBufferSize()1041 private void unsetBufferSize() { 1042 mWidth = 0; 1043 mHeight = 0; 1044 } 1045 1046 /** 1047 * Set the pixel format of the controlled surface's buffers, using constants from 1048 * {@link android.graphics.PixelFormat}. 1049 */ 1050 @NonNull setFormat(@ixelFormat.Format int format)1051 public Builder setFormat(@PixelFormat.Format int format) { 1052 mFormat = format; 1053 return this; 1054 } 1055 1056 /** 1057 * Specify if the app requires a hardware-protected path to 1058 * an external display sync. If protected content is enabled, but 1059 * such a path is not available, then the controlled Surface will 1060 * not be displayed. 1061 * 1062 * @param protectedContent Whether to require a protected sink. 1063 * @hide 1064 */ 1065 @NonNull setProtected(boolean protectedContent)1066 public Builder setProtected(boolean protectedContent) { 1067 if (protectedContent) { 1068 mFlags |= PROTECTED_APP; 1069 } else { 1070 mFlags &= ~PROTECTED_APP; 1071 } 1072 return this; 1073 } 1074 1075 /** 1076 * Specify whether the Surface contains secure content. If true, the system 1077 * will prevent the surfaces content from being copied by another process. In 1078 * particular screenshots and VNC servers will be disabled. This is however 1079 * not a complete prevention of readback as {@link #setProtected}. 1080 * @hide 1081 */ 1082 @NonNull setSecure(boolean secure)1083 public Builder setSecure(boolean secure) { 1084 if (secure) { 1085 mFlags |= SECURE; 1086 } else { 1087 mFlags &= ~SECURE; 1088 } 1089 return this; 1090 } 1091 1092 /** 1093 * Indicates whether the surface must be considered opaque, 1094 * even if its pixel format is set to translucent. This can be useful if an 1095 * application needs full RGBA 8888 support for instance but will 1096 * still draw every pixel opaque. 1097 * <p> 1098 * This flag only determines whether opacity will be sampled from the alpha channel. 1099 * Plane-alpha from calls to setAlpha() can still result in blended composition 1100 * regardless of the opaque setting. 1101 * 1102 * Combined effects are (assuming a buffer format with an alpha channel): 1103 * <ul> 1104 * <li>OPAQUE + alpha(1.0) == opaque composition 1105 * <li>OPAQUE + alpha(0.x) == blended composition 1106 * <li>OPAQUE + alpha(0.0) == no composition 1107 * <li>!OPAQUE + alpha(1.0) == blended composition 1108 * <li>!OPAQUE + alpha(0.x) == blended composition 1109 * <li>!OPAQUE + alpha(0.0) == no composition 1110 * </ul> 1111 * If the underlying buffer lacks an alpha channel, it is as if setOpaque(true) 1112 * were set automatically. 1113 * @param opaque Whether the Surface is OPAQUE. 1114 */ 1115 @NonNull setOpaque(boolean opaque)1116 public Builder setOpaque(boolean opaque) { 1117 if (opaque) { 1118 mFlags |= OPAQUE; 1119 } else { 1120 mFlags &= ~OPAQUE; 1121 } 1122 return this; 1123 } 1124 1125 /** 1126 * Set the initial visibility for the SurfaceControl. 1127 * 1128 * @param hidden Whether the Surface is initially HIDDEN. 1129 */ 1130 @NonNull setHidden(boolean hidden)1131 public Builder setHidden(boolean hidden) { 1132 if (hidden) { 1133 mFlags |= HIDDEN; 1134 } else { 1135 mFlags &= ~HIDDEN; 1136 } 1137 return this; 1138 } 1139 1140 /** 1141 * Set a parent surface for our new SurfaceControl. 1142 * 1143 * Child surfaces are constrained to the onscreen region of their parent. 1144 * Furthermore they stack relatively in Z order, and inherit the transformation 1145 * of the parent. 1146 * 1147 * @param parent The parent control. 1148 */ 1149 @NonNull setParent(@ullable SurfaceControl parent)1150 public Builder setParent(@Nullable SurfaceControl parent) { 1151 mParent = parent; 1152 return this; 1153 } 1154 1155 /** 1156 * Sets a metadata int. 1157 * 1158 * @param key metadata key 1159 * @param data associated data 1160 * @hide 1161 */ setMetadata(int key, int data)1162 public Builder setMetadata(int key, int data) { 1163 if (mMetadata == null) { 1164 mMetadata = new SparseIntArray(); 1165 } 1166 mMetadata.put(key, data); 1167 return this; 1168 } 1169 1170 /** 1171 * Indicate whether an 'EffectLayer' is to be constructed. 1172 * 1173 * An effect layer behaves like a container layer by default but it can support 1174 * color fill, shadows and/or blur. These layers will not have an associated buffer. 1175 * When created, this layer has no effects set and will be transparent but the caller 1176 * can render an effect by calling: 1177 * - {@link Transaction#setColor(SurfaceControl, float[])} 1178 * - {@link Transaction#setBackgroundBlurRadius(SurfaceControl, int)} 1179 * - {@link Transaction#setShadowRadius(SurfaceControl, float)} 1180 * 1181 * @hide 1182 */ setEffectLayer()1183 public Builder setEffectLayer() { 1184 mFlags |= NO_COLOR_FILL; 1185 unsetBufferSize(); 1186 return setFlags(FX_SURFACE_EFFECT, FX_SURFACE_MASK); 1187 } 1188 1189 /** 1190 * A convenience function to create an effect layer with a default color fill 1191 * applied to it. Currently that color is black. 1192 * 1193 * @hide 1194 */ setColorLayer()1195 public Builder setColorLayer() { 1196 unsetBufferSize(); 1197 return setFlags(FX_SURFACE_EFFECT, FX_SURFACE_MASK); 1198 } 1199 isEffectLayer()1200 private boolean isEffectLayer() { 1201 return (mFlags & FX_SURFACE_EFFECT) == FX_SURFACE_EFFECT; 1202 } 1203 1204 /** 1205 * @hide 1206 */ setBLASTLayer()1207 public Builder setBLASTLayer() { 1208 return setFlags(FX_SURFACE_BLAST, FX_SURFACE_MASK); 1209 } 1210 1211 /** 1212 * Indicates whether a 'ContainerLayer' is to be constructed. 1213 * 1214 * Container layers will not be rendered in any fashion and instead are used 1215 * as a parent of renderable layers. 1216 * 1217 * @hide 1218 */ setContainerLayer()1219 public Builder setContainerLayer() { 1220 unsetBufferSize(); 1221 return setFlags(FX_SURFACE_CONTAINER, FX_SURFACE_MASK); 1222 } 1223 isContainerLayer()1224 private boolean isContainerLayer() { 1225 return (mFlags & FX_SURFACE_CONTAINER) == FX_SURFACE_CONTAINER; 1226 } 1227 1228 /** 1229 * Set 'Surface creation flags' such as {@link #HIDDEN}, {@link #SECURE}. 1230 * 1231 * TODO: Finish conversion to individual builder methods? 1232 * @param flags The combined flags 1233 * @hide 1234 */ setFlags(int flags)1235 public Builder setFlags(int flags) { 1236 mFlags = flags; 1237 return this; 1238 } 1239 1240 /** 1241 * Sets the callsite this SurfaceControl is constructed from. 1242 * 1243 * @param callsite String uniquely identifying callsite that created this object. Used for 1244 * leakage tracking. 1245 * @hide 1246 */ setCallsite(String callsite)1247 public Builder setCallsite(String callsite) { 1248 mCallsite = callsite; 1249 return this; 1250 } 1251 setFlags(int flags, int mask)1252 private Builder setFlags(int flags, int mask) { 1253 mFlags = (mFlags & ~mask) | flags; 1254 return this; 1255 } 1256 } 1257 1258 /** 1259 * Create a surface with a name. 1260 * <p> 1261 * The surface creation flags specify what kind of surface to create and 1262 * certain options such as whether the surface can be assumed to be opaque 1263 * and whether it should be initially hidden. Surfaces should always be 1264 * created with the {@link #HIDDEN} flag set to ensure that they are not 1265 * made visible prematurely before all of the surface's properties have been 1266 * configured. 1267 * <p> 1268 * Good practice is to first create the surface with the {@link #HIDDEN} flag 1269 * specified, open a transaction, set the surface layer, layer stack, alpha, 1270 * and position, call {@link Transaction#show(SurfaceControl)} if appropriate, and close the 1271 * transaction. 1272 * <p> 1273 * Bounds of the surface is determined by its crop and its buffer size. If the 1274 * surface has no buffer or crop, the surface is boundless and only constrained 1275 * by the size of its parent bounds. 1276 * 1277 * @param session The surface session. 1278 * @param name The surface name, must not be null. 1279 * @param w The surface initial width. 1280 * @param h The surface initial height. 1281 * @param flags The surface creation flags. 1282 * @param metadata Initial metadata. 1283 * @param callsite String uniquely identifying callsite that created this object. Used for 1284 * leakage tracking. 1285 * @throws throws OutOfResourcesException If the SurfaceControl cannot be created. 1286 */ SurfaceControl(SurfaceSession session, String name, int w, int h, int format, int flags, SurfaceControl parent, SparseIntArray metadata, WeakReference<View> localOwnerView, String callsite)1287 private SurfaceControl(SurfaceSession session, String name, int w, int h, int format, int flags, 1288 SurfaceControl parent, SparseIntArray metadata, WeakReference<View> localOwnerView, 1289 String callsite) 1290 throws OutOfResourcesException, IllegalArgumentException { 1291 if (name == null) { 1292 throw new IllegalArgumentException("name must not be null"); 1293 } 1294 1295 mName = name; 1296 mWidth = w; 1297 mHeight = h; 1298 mLocalOwnerView = localOwnerView; 1299 Parcel metaParcel = Parcel.obtain(); 1300 long nativeObject = 0; 1301 try { 1302 if (metadata != null && metadata.size() > 0) { 1303 metaParcel.writeInt(metadata.size()); 1304 for (int i = 0; i < metadata.size(); ++i) { 1305 metaParcel.writeInt(metadata.keyAt(i)); 1306 metaParcel.writeByteArray( 1307 ByteBuffer.allocate(4).order(ByteOrder.nativeOrder()) 1308 .putInt(metadata.valueAt(i)).array()); 1309 } 1310 metaParcel.setDataPosition(0); 1311 } 1312 nativeObject = nativeCreate(session, name, w, h, format, flags, 1313 parent != null ? parent.mNativeObject : 0, metaParcel); 1314 } finally { 1315 metaParcel.recycle(); 1316 } 1317 if (nativeObject == 0) { 1318 throw new OutOfResourcesException( 1319 "Couldn't allocate SurfaceControl native object"); 1320 } 1321 assignNativeObject(nativeObject, callsite); 1322 } 1323 1324 /** 1325 * Copy constructor. Creates a new native object pointing to the same surface as {@code other}. 1326 * 1327 * @param other The object to copy the surface from. 1328 * @param callsite String uniquely identifying callsite that created this object. Used for 1329 * leakage tracking. 1330 * @hide 1331 */ 1332 @TestApi SurfaceControl(@onNull SurfaceControl other, @NonNull String callsite)1333 public SurfaceControl(@NonNull SurfaceControl other, @NonNull String callsite) { 1334 copyFrom(other, callsite); 1335 } 1336 SurfaceControl(Parcel in)1337 private SurfaceControl(Parcel in) { 1338 readFromParcel(in); 1339 } 1340 1341 /** 1342 * Note: Most callers should use {@link SurfaceControl.Builder} or one of the other constructors 1343 * to build an instance of a SurfaceControl. This constructor is mainly used for 1344 * unparceling and passing into an AIDL call as an out parameter. 1345 * @hide 1346 */ SurfaceControl()1347 public SurfaceControl() { 1348 } 1349 readFromParcel(Parcel in)1350 public void readFromParcel(Parcel in) { 1351 if (in == null) { 1352 throw new IllegalArgumentException("source must not be null"); 1353 } 1354 1355 mName = in.readString8(); 1356 mWidth = in.readInt(); 1357 mHeight = in.readInt(); 1358 1359 long object = 0; 1360 if (in.readInt() != 0) { 1361 object = nativeReadFromParcel(in); 1362 } 1363 assignNativeObject(object, "readFromParcel"); 1364 } 1365 1366 @Override describeContents()1367 public int describeContents() { 1368 return 0; 1369 } 1370 1371 @Override writeToParcel(Parcel dest, int flags)1372 public void writeToParcel(Parcel dest, int flags) { 1373 if (sDebugUsageAfterRelease) { 1374 checkNotReleased(); 1375 } 1376 dest.writeString8(mName); 1377 dest.writeInt(mWidth); 1378 dest.writeInt(mHeight); 1379 if (mNativeObject == 0) { 1380 dest.writeInt(0); 1381 } else { 1382 dest.writeInt(1); 1383 } 1384 nativeWriteToParcel(mNativeObject, dest); 1385 1386 if ((flags & Parcelable.PARCELABLE_WRITE_RETURN_VALUE) != 0) { 1387 release(); 1388 } 1389 } 1390 1391 /** 1392 * Enables additional debug logs to track usage-after-release of all SurfaceControls in this 1393 * process. 1394 * @hide 1395 */ setDebugUsageAfterRelease(boolean debug)1396 public static void setDebugUsageAfterRelease(boolean debug) { 1397 if (!Build.isDebuggable()) { 1398 return; 1399 } 1400 sDebugUsageAfterRelease = debug; 1401 } 1402 1403 /** 1404 * Provides more information to show about the source of this SurfaceControl if it is finalized 1405 * without being released. This is primarily intended for callers to update the call site after 1406 * receiving a SurfaceControl from another process, which would otherwise get a generic default 1407 * call site. 1408 * @hide 1409 */ setUnreleasedWarningCallSite(@onNull String callsite)1410 public void setUnreleasedWarningCallSite(@NonNull String callsite) { 1411 if (!isValid()) { 1412 return; 1413 } 1414 mCloseGuard.openWithCallSite("release", callsite); 1415 mCallsite = callsite; 1416 } 1417 1418 /** 1419 * Returns the last provided call site when this SurfaceControl was created. 1420 * @hide 1421 */ getCallsite()1422 @Nullable String getCallsite() { 1423 return mCallsite; 1424 } 1425 1426 /** 1427 * Returns the name of this SurfaceControl, mainly for debugging purposes. 1428 * @hide 1429 */ getName()1430 @NonNull String getName() { 1431 return mName; 1432 } 1433 1434 /** 1435 * Checks whether two {@link SurfaceControl} objects represent the same surface. 1436 * 1437 * @param other The other object to check 1438 * @return {@code true} if these two {@link SurfaceControl} objects represent the same surface. 1439 * @hide 1440 */ 1441 @TestApi isSameSurface(@onNull SurfaceControl other)1442 public boolean isSameSurface(@NonNull SurfaceControl other) { 1443 return other.mNativeHandle == mNativeHandle; 1444 } 1445 1446 /** 1447 * When called for the first time a new instance of the {@link Choreographer} is created 1448 * with a {@link android.os.Looper} of the current thread. Every subsequent call will return 1449 * the same instance of the Choreographer. 1450 * 1451 * @see #getChoreographer(Looper) to create Choreographer with a different 1452 * looper than current thread looper. 1453 * 1454 * @hide 1455 */ 1456 @TestApi getChoreographer()1457 public @NonNull Choreographer getChoreographer() { 1458 checkNotReleased(); 1459 synchronized (mChoreographerLock) { 1460 if (mChoreographer == null) { 1461 return getChoreographer(Looper.myLooper()); 1462 } 1463 return mChoreographer; 1464 } 1465 } 1466 1467 /** 1468 * When called for the first time a new instance of the {@link Choreographer} is created with 1469 * the sourced {@link android.os.Looper}. Every subsequent call will return the same 1470 * instance of the Choreographer. 1471 * 1472 * @see #getChoreographer() 1473 * 1474 * @throws IllegalStateException when a {@link Choreographer} instance exists with a different 1475 * looper than sourced. 1476 * @param looper the choreographer is attached on this looper. 1477 * 1478 * @hide 1479 */ 1480 @TestApi getChoreographer(@onNull Looper looper)1481 public @NonNull Choreographer getChoreographer(@NonNull Looper looper) { 1482 checkNotReleased(); 1483 synchronized (mChoreographerLock) { 1484 if (mChoreographer == null) { 1485 mChoreographer = Choreographer.getInstanceForSurfaceControl(mNativeHandle, looper); 1486 } else if (!mChoreographer.isTheLooperSame(looper)) { 1487 throw new IllegalStateException( 1488 "Choreographer already exists with a different looper"); 1489 } 1490 return mChoreographer; 1491 } 1492 } 1493 1494 /** 1495 * Returns true if {@link Choreographer} is present otherwise false. 1496 * To check the validity use {@link #isValid} on the SurfaceControl, a valid SurfaceControl with 1497 * choreographer will have the valid Choreographer. 1498 * 1499 * @hide 1500 */ 1501 @TestApi 1502 @UnsupportedAppUsage hasChoreographer()1503 public boolean hasChoreographer() { 1504 synchronized (mChoreographerLock) { 1505 return mChoreographer != null; 1506 } 1507 } 1508 1509 /** 1510 * Write to a protocol buffer output stream. Protocol buffer message definition is at {@link 1511 * android.view.SurfaceControlProto}. 1512 * 1513 * @param proto Stream to write the SurfaceControl object to. 1514 * @param fieldId Field Id of the SurfaceControl as defined in the parent message. 1515 * @hide 1516 */ dumpDebug(ProtoOutputStream proto, long fieldId)1517 public void dumpDebug(ProtoOutputStream proto, long fieldId) { 1518 final long token = proto.start(fieldId); 1519 proto.write(HASH_CODE, System.identityHashCode(this)); 1520 proto.write(NAME, mName); 1521 proto.write(LAYER_ID, getLayerId()); 1522 proto.end(token); 1523 } 1524 1525 public static final @android.annotation.NonNull Creator<SurfaceControl> CREATOR 1526 = new Creator<SurfaceControl>() { 1527 public SurfaceControl createFromParcel(Parcel in) { 1528 return new SurfaceControl(in); 1529 } 1530 1531 public SurfaceControl[] newArray(int size) { 1532 return new SurfaceControl[size]; 1533 } 1534 }; 1535 1536 /** 1537 * @hide 1538 */ 1539 @Override finalize()1540 protected void finalize() throws Throwable { 1541 try { 1542 if (mCloseGuard != null) { 1543 mCloseGuard.warnIfOpen(); 1544 } 1545 SurfaceControlRegistry.getProcessInstance().remove(this); 1546 } finally { 1547 super.finalize(); 1548 } 1549 } 1550 1551 /** 1552 * Release the local reference to the server-side surface. The surface 1553 * may continue to exist on-screen as long as its parent continues 1554 * to exist. To explicitly remove a surface from the screen use 1555 * {@link Transaction#reparent} with a null-parent. After release, 1556 * {@link #isValid} will return false and other methods will throw 1557 * an exception. 1558 * 1559 * Always call release() when you're done with a SurfaceControl. 1560 */ release()1561 public void release() { 1562 if (mNativeObject != 0) { 1563 if (SurfaceControlRegistry.sCallStackDebuggingEnabled) { 1564 SurfaceControlRegistry.getProcessInstance().checkCallStackDebugging( 1565 "release", null, this, null); 1566 } 1567 mFreeNativeResources.run(); 1568 mNativeObject = 0; 1569 mNativeHandle = 0; 1570 if (sDebugUsageAfterRelease) { 1571 mReleaseStack = new Throwable("Released"); 1572 } 1573 mCloseGuard.close(); 1574 synchronized (mChoreographerLock) { 1575 if (mChoreographer != null) { 1576 mChoreographer.invalidate(); 1577 mChoreographer = null; 1578 } 1579 } 1580 SurfaceControlRegistry.getProcessInstance().remove(this); 1581 } 1582 } 1583 1584 /** 1585 * Disconnect any client still connected to the surface. 1586 * @hide 1587 */ disconnect()1588 public void disconnect() { 1589 if (mNativeObject != 0) { 1590 nativeDisconnect(mNativeObject); 1591 } 1592 } 1593 checkNotReleased()1594 private void checkNotReleased() { 1595 if (mNativeObject == 0) { 1596 if (mReleaseStack != null) { 1597 throw new IllegalStateException("Invalid usage after release of " + this, 1598 mReleaseStack); 1599 } else { 1600 throw new NullPointerException("mNativeObject of " + this 1601 + " is null. Have you called release() already?"); 1602 } 1603 } 1604 } 1605 1606 /** 1607 * Check whether this instance points to a valid layer with the system-compositor. For 1608 * example this may be false if construction failed, or the layer was released 1609 * ({@link #release}). 1610 * 1611 * @return Whether this SurfaceControl is valid. 1612 */ isValid()1613 public boolean isValid() { 1614 return mNativeObject != 0; 1615 } 1616 1617 /** start a transaction 1618 * @hide 1619 * @deprecated Use regular Transaction instead. 1620 */ 1621 @Deprecated 1622 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.VANILLA_ICE_CREAM, 1623 publicAlternatives = "Use {@code SurfaceControl.Transaction} instead", 1624 trackingBug = 247078497) openTransaction()1625 public static void openTransaction() { 1626 // TODO(b/247078497): It was used for global transaction (all usages are removed). 1627 // Keep the method declaration to avoid breaking reference from legacy access. 1628 } 1629 1630 /** end a transaction 1631 * @hide 1632 * @deprecated Use regular Transaction instead. 1633 */ 1634 @Deprecated 1635 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.VANILLA_ICE_CREAM, 1636 publicAlternatives = "Use {@code SurfaceControl.Transaction} instead", 1637 trackingBug = 247078497) closeTransaction()1638 public static void closeTransaction() { 1639 // TODO(b/247078497): It was used for global transaction (all usages are removed). 1640 // Keep the method declaration to avoid breaking reference from legacy access. 1641 } 1642 1643 /** 1644 * @hide 1645 */ clearContentFrameStats()1646 public boolean clearContentFrameStats() { 1647 checkNotReleased(); 1648 return nativeClearContentFrameStats(mNativeObject); 1649 } 1650 1651 /** 1652 * @hide 1653 */ getContentFrameStats(WindowContentFrameStats outStats)1654 public boolean getContentFrameStats(WindowContentFrameStats outStats) { 1655 checkNotReleased(); 1656 return nativeGetContentFrameStats(mNativeObject, outStats); 1657 } 1658 1659 /** 1660 * @hide 1661 */ clearAnimationFrameStats()1662 public static boolean clearAnimationFrameStats() { 1663 return nativeClearAnimationFrameStats(); 1664 } 1665 1666 /** 1667 * @hide 1668 */ getAnimationFrameStats(WindowAnimationFrameStats outStats)1669 public static boolean getAnimationFrameStats(WindowAnimationFrameStats outStats) { 1670 return nativeGetAnimationFrameStats(outStats); 1671 } 1672 1673 /** 1674 * @hide 1675 */ getWidth()1676 public int getWidth() { 1677 synchronized (mLock) { 1678 return mWidth; 1679 } 1680 } 1681 1682 /** 1683 * @hide 1684 */ getHeight()1685 public int getHeight() { 1686 synchronized (mLock) { 1687 return mHeight; 1688 } 1689 } 1690 1691 /** 1692 * Gets the local view that owns this surface. 1693 * 1694 * @return The owner view. 1695 * 1696 * @hide 1697 */ getLocalOwnerView()1698 public @Nullable View getLocalOwnerView() { 1699 return (mLocalOwnerView != null) ? mLocalOwnerView.get() : null; 1700 } 1701 1702 @Override toString()1703 public String toString() { 1704 return "Surface(name=" + mName + ")/@0x" + 1705 Integer.toHexString(System.identityHashCode(this)); 1706 } 1707 1708 /** 1709 * Immutable information about physical display. 1710 * 1711 * @hide 1712 */ 1713 public static final class StaticDisplayInfo { 1714 public boolean isInternal; 1715 public float density; 1716 public boolean secure; 1717 public DeviceProductInfo deviceProductInfo; 1718 public @Surface.Rotation int installOrientation; 1719 1720 @Override toString()1721 public String toString() { 1722 return "StaticDisplayInfo{isInternal=" + isInternal 1723 + ", density=" + density 1724 + ", secure=" + secure 1725 + ", deviceProductInfo=" + deviceProductInfo 1726 + ", installOrientation=" + installOrientation + "}"; 1727 } 1728 1729 @Override equals(@ullable Object o)1730 public boolean equals(@Nullable Object o) { 1731 if (this == o) return true; 1732 if (o == null || getClass() != o.getClass()) return false; 1733 StaticDisplayInfo that = (StaticDisplayInfo) o; 1734 return isInternal == that.isInternal 1735 && density == that.density 1736 && secure == that.secure 1737 && Objects.equals(deviceProductInfo, that.deviceProductInfo) 1738 && installOrientation == that.installOrientation; 1739 } 1740 1741 @Override hashCode()1742 public int hashCode() { 1743 return Objects.hash(isInternal, density, secure, deviceProductInfo, installOrientation); 1744 } 1745 } 1746 1747 /** 1748 * Dynamic information about physical display. 1749 * 1750 * @hide 1751 */ 1752 public static final class DynamicDisplayInfo { 1753 public DisplayMode[] supportedDisplayModes; 1754 public int activeDisplayModeId; 1755 public float renderFrameRate; 1756 1757 public int[] supportedColorModes; 1758 public int activeColorMode; 1759 1760 public Display.HdrCapabilities hdrCapabilities; 1761 1762 public boolean autoLowLatencyModeSupported; 1763 public boolean gameContentTypeSupported; 1764 1765 public int preferredBootDisplayMode; 1766 1767 @Override toString()1768 public String toString() { 1769 return "DynamicDisplayInfo{" 1770 + "supportedDisplayModes=" + Arrays.toString(supportedDisplayModes) 1771 + ", activeDisplayModeId=" + activeDisplayModeId 1772 + ", renderFrameRate=" + renderFrameRate 1773 + ", supportedColorModes=" + Arrays.toString(supportedColorModes) 1774 + ", activeColorMode=" + activeColorMode 1775 + ", hdrCapabilities=" + hdrCapabilities 1776 + ", autoLowLatencyModeSupported=" + autoLowLatencyModeSupported 1777 + ", gameContentTypeSupported" + gameContentTypeSupported 1778 + ", preferredBootDisplayMode" + preferredBootDisplayMode + "}"; 1779 } 1780 1781 @Override equals(@ullable Object o)1782 public boolean equals(@Nullable Object o) { 1783 if (this == o) return true; 1784 if (o == null || getClass() != o.getClass()) return false; 1785 DynamicDisplayInfo that = (DynamicDisplayInfo) o; 1786 return Arrays.equals(supportedDisplayModes, that.supportedDisplayModes) 1787 && activeDisplayModeId == that.activeDisplayModeId 1788 && renderFrameRate == that.renderFrameRate 1789 && Arrays.equals(supportedColorModes, that.supportedColorModes) 1790 && activeColorMode == that.activeColorMode 1791 && Objects.equals(hdrCapabilities, that.hdrCapabilities) 1792 && preferredBootDisplayMode == that.preferredBootDisplayMode; 1793 } 1794 1795 @Override hashCode()1796 public int hashCode() { 1797 return Objects.hash(Arrays.hashCode(supportedDisplayModes), activeDisplayModeId, 1798 renderFrameRate, activeColorMode, hdrCapabilities); 1799 } 1800 } 1801 1802 /** 1803 * Configuration supported by physical display. 1804 * 1805 * @hide 1806 */ 1807 public static final class DisplayMode { 1808 public int id; 1809 public int width; 1810 public int height; 1811 public float xDpi; 1812 public float yDpi; 1813 1814 // Some modes have peak refresh rate lower than the panel vsync rate. 1815 public float peakRefreshRate; 1816 // Fixed rate of vsync deadlines for the panel. 1817 // This can be higher then the peak refresh rate for some panel technologies 1818 // See: VrrConfig.aidl 1819 public float vsyncRate; 1820 public long appVsyncOffsetNanos; 1821 public long presentationDeadlineNanos; 1822 public int[] supportedHdrTypes; 1823 1824 /** 1825 * The config group ID this config is associated to. 1826 * Configs in the same group are similar from vendor's perspective and switching between 1827 * configs within the same group can be done seamlessly in most cases. 1828 * @see: android.hardware.graphics.composer@2.4::IComposerClient::Attribute::CONFIG_GROUP 1829 */ 1830 public int group; 1831 1832 @Override toString()1833 public String toString() { 1834 return "DisplayMode{id=" + id 1835 + ", width=" + width 1836 + ", height=" + height 1837 + ", xDpi=" + xDpi 1838 + ", yDpi=" + yDpi 1839 + ", peakRefreshRate=" + peakRefreshRate 1840 + ", vsyncRate=" + vsyncRate 1841 + ", appVsyncOffsetNanos=" + appVsyncOffsetNanos 1842 + ", presentationDeadlineNanos=" + presentationDeadlineNanos 1843 + ", supportedHdrTypes=" + Arrays.toString(supportedHdrTypes) 1844 + ", group=" + group + "}"; 1845 } 1846 1847 @Override equals(Object o)1848 public boolean equals(Object o) { 1849 if (this == o) return true; 1850 if (o == null || getClass() != o.getClass()) return false; 1851 DisplayMode that = (DisplayMode) o; 1852 return id == that.id 1853 && width == that.width 1854 && height == that.height 1855 && Float.compare(that.xDpi, xDpi) == 0 1856 && Float.compare(that.yDpi, yDpi) == 0 1857 && Float.compare(that.peakRefreshRate, peakRefreshRate) == 0 1858 && Float.compare(that.vsyncRate, vsyncRate) == 0 1859 && appVsyncOffsetNanos == that.appVsyncOffsetNanos 1860 && presentationDeadlineNanos == that.presentationDeadlineNanos 1861 && Arrays.equals(supportedHdrTypes, that.supportedHdrTypes) 1862 && group == that.group; 1863 } 1864 1865 @Override hashCode()1866 public int hashCode() { 1867 return Objects.hash(id, width, height, xDpi, yDpi, peakRefreshRate, vsyncRate, 1868 appVsyncOffsetNanos, presentationDeadlineNanos, group, 1869 Arrays.hashCode(supportedHdrTypes)); 1870 } 1871 } 1872 1873 /** 1874 * @hide 1875 */ setDisplayPowerMode(IBinder displayToken, int mode)1876 public static void setDisplayPowerMode(IBinder displayToken, int mode) { 1877 if (displayToken == null) { 1878 throw new IllegalArgumentException("displayToken must not be null"); 1879 } 1880 nativeSetDisplayPowerMode(displayToken, mode); 1881 } 1882 1883 /** 1884 * @hide 1885 */ getStaticDisplayInfo(long displayId)1886 public static StaticDisplayInfo getStaticDisplayInfo(long displayId) { 1887 return nativeGetStaticDisplayInfo(displayId); 1888 } 1889 1890 /** 1891 * @hide 1892 */ getDynamicDisplayInfo(long displayId)1893 public static DynamicDisplayInfo getDynamicDisplayInfo(long displayId) { 1894 return nativeGetDynamicDisplayInfo(displayId); 1895 } 1896 1897 /** 1898 * @hide 1899 */ getDisplayedContentSamplingAttributes( IBinder displayToken)1900 public static DisplayedContentSamplingAttributes getDisplayedContentSamplingAttributes( 1901 IBinder displayToken) { 1902 if (displayToken == null) { 1903 throw new IllegalArgumentException("displayToken must not be null"); 1904 } 1905 return nativeGetDisplayedContentSamplingAttributes(displayToken); 1906 } 1907 1908 /** 1909 * @hide 1910 */ setDisplayedContentSamplingEnabled( IBinder displayToken, boolean enable, int componentMask, int maxFrames)1911 public static boolean setDisplayedContentSamplingEnabled( 1912 IBinder displayToken, boolean enable, int componentMask, int maxFrames) { 1913 if (displayToken == null) { 1914 throw new IllegalArgumentException("displayToken must not be null"); 1915 } 1916 final int maxColorComponents = 4; 1917 if ((componentMask >> maxColorComponents) != 0) { 1918 throw new IllegalArgumentException("invalid componentMask when enabling sampling"); 1919 } 1920 return nativeSetDisplayedContentSamplingEnabled( 1921 displayToken, enable, componentMask, maxFrames); 1922 } 1923 1924 /** 1925 * @hide 1926 */ getDisplayedContentSample( IBinder displayToken, long maxFrames, long timestamp)1927 public static DisplayedContentSample getDisplayedContentSample( 1928 IBinder displayToken, long maxFrames, long timestamp) { 1929 if (displayToken == null) { 1930 throw new IllegalArgumentException("displayToken must not be null"); 1931 } 1932 return nativeGetDisplayedContentSample(displayToken, maxFrames, timestamp); 1933 } 1934 1935 /** 1936 * Information about the min and max refresh rate DM would like to set the display to. 1937 * @hide 1938 */ 1939 public static final class RefreshRateRange implements Parcelable { 1940 public static final String TAG = "RefreshRateRange"; 1941 1942 // The tolerance within which we consider something approximately equals. 1943 public static final float FLOAT_TOLERANCE = 0.01f; 1944 1945 /** 1946 * The lowest desired refresh rate. 1947 */ 1948 public float min; 1949 1950 /** 1951 * The highest desired refresh rate. 1952 */ 1953 public float max; 1954 RefreshRateRange()1955 public RefreshRateRange() {} 1956 RefreshRateRange(float min, float max)1957 public RefreshRateRange(float min, float max) { 1958 if (min < 0 || max < 0 || min > max + FLOAT_TOLERANCE) { 1959 Slog.e(TAG, "Wrong values for min and max when initializing RefreshRateRange : " 1960 + min + " " + max); 1961 this.min = this.max = 0; 1962 return; 1963 } 1964 if (min > max) { 1965 // Min and max are within epsilon of each other, but in the wrong order. 1966 float t = min; 1967 min = max; 1968 max = t; 1969 } 1970 this.min = min; 1971 this.max = max; 1972 } 1973 1974 /** 1975 * Checks whether the two objects have the same values. 1976 */ 1977 @Override equals(Object other)1978 public boolean equals(Object other) { 1979 if (other == this) { 1980 return true; 1981 } 1982 1983 if (!(other instanceof RefreshRateRange)) { 1984 return false; 1985 } 1986 1987 RefreshRateRange refreshRateRange = (RefreshRateRange) other; 1988 return (min == refreshRateRange.min && max == refreshRateRange.max); 1989 } 1990 1991 @Override hashCode()1992 public int hashCode() { 1993 return Objects.hash(min, max); 1994 } 1995 1996 @Override toString()1997 public String toString() { 1998 return "(" + min + " " + max + ")"; 1999 } 2000 2001 /** 2002 * Copies the supplied object's values to this object. 2003 */ copyFrom(RefreshRateRange other)2004 public void copyFrom(RefreshRateRange other) { 2005 this.min = other.min; 2006 this.max = other.max; 2007 } 2008 2009 /** 2010 * Writes the RefreshRateRange to parce 2011 * 2012 * @param dest parcel to write the transaction to 2013 */ 2014 @Override writeToParcel(@onNull Parcel dest, @WriteFlags int flags)2015 public void writeToParcel(@NonNull Parcel dest, @WriteFlags int flags) { 2016 dest.writeFloat(min); 2017 dest.writeFloat(max); 2018 } 2019 2020 @Override describeContents()2021 public int describeContents() { 2022 return 0; 2023 } 2024 2025 public static final @NonNull Creator<RefreshRateRange> CREATOR = 2026 new Creator<RefreshRateRange>() { 2027 @Override 2028 public RefreshRateRange createFromParcel(Parcel in) { 2029 return new RefreshRateRange(in.readFloat(), in.readFloat()); 2030 } 2031 2032 @Override 2033 public RefreshRateRange[] newArray(int size) { 2034 return new RefreshRateRange[size]; 2035 } 2036 }; 2037 } 2038 2039 /** 2040 * Information about the ranges of refresh rates for the display physical refresh rates and the 2041 * render frame rate DM would like to set the policy to. 2042 * @hide 2043 */ 2044 public static final class RefreshRateRanges { 2045 public static final String TAG = "RefreshRateRanges"; 2046 2047 /** 2048 * The range of refresh rates that the display should run at. 2049 */ 2050 public final RefreshRateRange physical; 2051 2052 /** 2053 * The range of refresh rates that apps should render at. 2054 */ 2055 public final RefreshRateRange render; 2056 RefreshRateRanges()2057 public RefreshRateRanges() { 2058 physical = new RefreshRateRange(); 2059 render = new RefreshRateRange(); 2060 } 2061 RefreshRateRanges(RefreshRateRange physical, RefreshRateRange render)2062 public RefreshRateRanges(RefreshRateRange physical, RefreshRateRange render) { 2063 this.physical = new RefreshRateRange(physical.min, physical.max); 2064 this.render = new RefreshRateRange(render.min, render.max); 2065 } 2066 2067 /** 2068 * Checks whether the two objects have the same values. 2069 */ 2070 @Override equals(Object other)2071 public boolean equals(Object other) { 2072 if (other == this) { 2073 return true; 2074 } 2075 2076 if (!(other instanceof RefreshRateRanges)) { 2077 return false; 2078 } 2079 2080 RefreshRateRanges rates = (RefreshRateRanges) other; 2081 return physical.equals(rates.physical) && render.equals( 2082 rates.render); 2083 } 2084 2085 @Override hashCode()2086 public int hashCode() { 2087 return Objects.hash(physical, render); 2088 } 2089 2090 @Override toString()2091 public String toString() { 2092 return "physical: " + physical + " render: " + render; 2093 } 2094 2095 /** 2096 * Copies the supplied object's values to this object. 2097 */ copyFrom(RefreshRateRanges other)2098 public void copyFrom(RefreshRateRanges other) { 2099 this.physical.copyFrom(other.physical); 2100 this.render.copyFrom(other.render); 2101 } 2102 } 2103 2104 /** 2105 * Contains information of the idle time of the screen after which the refresh rate is to be 2106 * reduced. 2107 * 2108 * @hide 2109 */ 2110 public static final class IdleScreenRefreshRateConfig { 2111 /** 2112 * The time(in ms) after which the refresh rate is to be reduced. Defaults to -1, which 2113 * means no timeout has been configured for the current conditions 2114 */ 2115 public int timeoutMillis; 2116 IdleScreenRefreshRateConfig()2117 public IdleScreenRefreshRateConfig() { 2118 timeoutMillis = -1; 2119 } 2120 IdleScreenRefreshRateConfig(int timeoutMillis)2121 public IdleScreenRefreshRateConfig(int timeoutMillis) { 2122 this.timeoutMillis = timeoutMillis; 2123 } 2124 2125 /** 2126 * Checks whether the two objects have the same values. 2127 */ 2128 @Override equals(Object other)2129 public boolean equals(Object other) { 2130 if (other == this) { 2131 return true; 2132 } 2133 2134 if (!(other instanceof IdleScreenRefreshRateConfig) || other == null) { 2135 return false; 2136 } 2137 2138 IdleScreenRefreshRateConfig 2139 idleScreenRefreshRateConfig = (IdleScreenRefreshRateConfig) other; 2140 return timeoutMillis == idleScreenRefreshRateConfig.timeoutMillis; 2141 } 2142 2143 @Override hashCode()2144 public int hashCode() { 2145 return Objects.hash(timeoutMillis); 2146 } 2147 2148 @Override toString()2149 public String toString() { 2150 return "timeoutMillis: " + timeoutMillis; 2151 } 2152 2153 /** 2154 * Copies the supplied object's values to this object. 2155 */ copyFrom(IdleScreenRefreshRateConfig other)2156 public void copyFrom(IdleScreenRefreshRateConfig other) { 2157 if (other != null) { 2158 this.timeoutMillis = other.timeoutMillis; 2159 } 2160 } 2161 } 2162 2163 2164 /** 2165 * Contains information about desired display configuration. 2166 * 2167 * @hide 2168 */ 2169 public static final class DesiredDisplayModeSpecs { 2170 public int defaultMode; 2171 /** 2172 * If true this will allow switching between modes in different display configuration 2173 * groups. This way the user may see visual interruptions when the display mode changes. 2174 */ 2175 public boolean allowGroupSwitching; 2176 2177 /** 2178 * The primary physical and render refresh rate ranges represent display manager's general 2179 * guidance on the display configs surface flinger will consider when switching refresh 2180 * rates and scheduling the frame rate. Unless surface flinger has a specific reason to do 2181 * otherwise, it will stay within this range. 2182 */ 2183 public final RefreshRateRanges primaryRanges; 2184 2185 /** 2186 * The app request physical and render refresh rate ranges allow surface flinger to consider 2187 * more display configs when switching refresh rates. Although surface flinger will 2188 * generally stay within the primary range, specific considerations, such as layer frame 2189 * rate settings specified via the setFrameRate() api, may cause surface flinger to go 2190 * outside the primary range. Surface flinger never goes outside the app request range. 2191 * The app request range will be greater than or equal to the primary refresh rate range, 2192 * never smaller. 2193 */ 2194 public final RefreshRateRanges appRequestRanges; 2195 2196 /** 2197 * Represents the idle time of the screen after which the associated display's refresh rate 2198 * is to be reduced to preserve power 2199 * Defaults to null, meaning that the device is not configured to have a timeout. 2200 * Timeout value of -1 refers that the current conditions require no timeout 2201 */ 2202 @Nullable 2203 public IdleScreenRefreshRateConfig idleScreenRefreshRateConfig; 2204 DesiredDisplayModeSpecs()2205 public DesiredDisplayModeSpecs() { 2206 this.primaryRanges = new RefreshRateRanges(); 2207 this.appRequestRanges = new RefreshRateRanges(); 2208 } 2209 DesiredDisplayModeSpecs(DesiredDisplayModeSpecs other)2210 public DesiredDisplayModeSpecs(DesiredDisplayModeSpecs other) { 2211 this.primaryRanges = new RefreshRateRanges(); 2212 this.appRequestRanges = new RefreshRateRanges(); 2213 copyFrom(other); 2214 } 2215 DesiredDisplayModeSpecs(int defaultMode, boolean allowGroupSwitching, RefreshRateRanges primaryRanges, RefreshRateRanges appRequestRanges, @Nullable IdleScreenRefreshRateConfig idleScreenRefreshRateConfig)2216 public DesiredDisplayModeSpecs(int defaultMode, boolean allowGroupSwitching, 2217 RefreshRateRanges primaryRanges, RefreshRateRanges appRequestRanges, 2218 @Nullable IdleScreenRefreshRateConfig idleScreenRefreshRateConfig) { 2219 this.defaultMode = defaultMode; 2220 this.allowGroupSwitching = allowGroupSwitching; 2221 this.primaryRanges = 2222 new RefreshRateRanges(primaryRanges.physical, primaryRanges.render); 2223 this.appRequestRanges = 2224 new RefreshRateRanges(appRequestRanges.physical, appRequestRanges.render); 2225 this.idleScreenRefreshRateConfig = 2226 (idleScreenRefreshRateConfig == null) ? null : new IdleScreenRefreshRateConfig( 2227 idleScreenRefreshRateConfig.timeoutMillis); 2228 } 2229 2230 @Override equals(@ullable Object o)2231 public boolean equals(@Nullable Object o) { 2232 return o instanceof DesiredDisplayModeSpecs && equals((DesiredDisplayModeSpecs) o); 2233 } 2234 2235 /** 2236 * Tests for equality. 2237 */ equals(DesiredDisplayModeSpecs other)2238 public boolean equals(DesiredDisplayModeSpecs other) { 2239 return other != null && defaultMode == other.defaultMode 2240 && allowGroupSwitching == other.allowGroupSwitching 2241 && primaryRanges.equals(other.primaryRanges) 2242 && appRequestRanges.equals(other.appRequestRanges) 2243 && Objects.equals( 2244 idleScreenRefreshRateConfig, other.idleScreenRefreshRateConfig); 2245 } 2246 2247 @Override hashCode()2248 public int hashCode() { 2249 return 0; // don't care 2250 } 2251 2252 /** 2253 * Copies the supplied object's values to this object. 2254 */ copyFrom(DesiredDisplayModeSpecs other)2255 public void copyFrom(DesiredDisplayModeSpecs other) { 2256 defaultMode = other.defaultMode; 2257 allowGroupSwitching = other.allowGroupSwitching; 2258 primaryRanges.copyFrom(other.primaryRanges); 2259 appRequestRanges.copyFrom(other.appRequestRanges); 2260 copyIdleScreenRefreshRateConfig(other.idleScreenRefreshRateConfig); 2261 } 2262 2263 @Override toString()2264 public String toString() { 2265 return "defaultMode=" + defaultMode 2266 + " allowGroupSwitching=" + allowGroupSwitching 2267 + " primaryRanges=" + primaryRanges 2268 + " appRequestRanges=" + appRequestRanges 2269 + " idleScreenRefreshRate=" + String.valueOf(idleScreenRefreshRateConfig); 2270 } 2271 copyIdleScreenRefreshRateConfig(IdleScreenRefreshRateConfig other)2272 private void copyIdleScreenRefreshRateConfig(IdleScreenRefreshRateConfig other) { 2273 if (idleScreenRefreshRateConfig == null) { 2274 if (other != null) { 2275 idleScreenRefreshRateConfig = 2276 new IdleScreenRefreshRateConfig(other.timeoutMillis); 2277 } 2278 } else if (other == null) { 2279 idleScreenRefreshRateConfig = null; 2280 } else { 2281 idleScreenRefreshRateConfig.copyFrom(other); 2282 } 2283 } 2284 } 2285 2286 /** 2287 * @hide 2288 */ setDesiredDisplayModeSpecs(IBinder displayToken, DesiredDisplayModeSpecs desiredDisplayModeSpecs)2289 public static boolean setDesiredDisplayModeSpecs(IBinder displayToken, 2290 DesiredDisplayModeSpecs desiredDisplayModeSpecs) { 2291 if (displayToken == null) { 2292 throw new IllegalArgumentException("displayToken must not be null"); 2293 } 2294 if (desiredDisplayModeSpecs == null) { 2295 throw new IllegalArgumentException("desiredDisplayModeSpecs must not be null"); 2296 } 2297 if (desiredDisplayModeSpecs.defaultMode < 0) { 2298 throw new IllegalArgumentException("defaultMode must be non-negative"); 2299 } 2300 2301 return nativeSetDesiredDisplayModeSpecs(displayToken, desiredDisplayModeSpecs); 2302 } 2303 2304 /** 2305 * @hide 2306 */ getDesiredDisplayModeSpecs( IBinder displayToken)2307 public static DesiredDisplayModeSpecs getDesiredDisplayModeSpecs( 2308 IBinder displayToken) { 2309 if (displayToken == null) { 2310 throw new IllegalArgumentException("displayToken must not be null"); 2311 } 2312 2313 return nativeGetDesiredDisplayModeSpecs(displayToken); 2314 } 2315 2316 /** 2317 * Color coordinates in CIE1931 XYZ color space 2318 * 2319 * @hide 2320 */ 2321 public static final class CieXyz { 2322 /** 2323 * @hide 2324 */ 2325 public float X; 2326 2327 /** 2328 * @hide 2329 */ 2330 public float Y; 2331 2332 /** 2333 * @hide 2334 */ 2335 public float Z; 2336 } 2337 2338 /** 2339 * Contains a display's color primaries 2340 * 2341 * @hide 2342 */ 2343 public static final class DisplayPrimaries { 2344 /** 2345 * @hide 2346 */ 2347 public CieXyz red; 2348 2349 /** 2350 * @hide 2351 */ 2352 public CieXyz green; 2353 2354 /** 2355 * @hide 2356 */ 2357 public CieXyz blue; 2358 2359 /** 2360 * @hide 2361 */ 2362 public CieXyz white; 2363 2364 /** 2365 * @hide 2366 */ DisplayPrimaries()2367 public DisplayPrimaries() { 2368 } 2369 } 2370 2371 /** 2372 * @hide 2373 */ getDisplayNativePrimaries( IBinder displayToken)2374 public static DisplayPrimaries getDisplayNativePrimaries( 2375 IBinder displayToken) { 2376 if (displayToken == null) { 2377 throw new IllegalArgumentException("displayToken must not be null"); 2378 } 2379 2380 return nativeGetDisplayNativePrimaries(displayToken); 2381 } 2382 2383 /** 2384 * @hide 2385 */ setActiveColorMode(IBinder displayToken, int colorMode)2386 public static boolean setActiveColorMode(IBinder displayToken, int colorMode) { 2387 if (displayToken == null) { 2388 throw new IllegalArgumentException("displayToken must not be null"); 2389 } 2390 return nativeSetActiveColorMode(displayToken, colorMode); 2391 } 2392 2393 /** 2394 * Returns an array of color spaces with 2 elements. The first color space is the 2395 * default color space and second one is wide color gamut color space. 2396 * @hide 2397 */ getCompositionColorSpaces()2398 public static ColorSpace[] getCompositionColorSpaces() { 2399 int[] dataspaces = nativeGetCompositionDataspaces(); 2400 ColorSpace srgb = ColorSpace.get(ColorSpace.Named.SRGB); 2401 ColorSpace[] colorSpaces = { srgb, srgb }; 2402 if (dataspaces.length == 2) { 2403 for (int i = 0; i < 2; ++i) { 2404 ColorSpace cs = ColorSpace.getFromDataSpace(dataspaces[i]); 2405 if (cs != null) { 2406 colorSpaces[i] = cs; 2407 } 2408 } 2409 } 2410 return colorSpaces; 2411 } 2412 2413 /** 2414 * @return the overlay properties of the device 2415 * @hide 2416 */ getOverlaySupport()2417 public static OverlayProperties getOverlaySupport() { 2418 return nativeGetOverlaySupport(); 2419 } 2420 2421 /** 2422 * @hide 2423 */ getBootDisplayModeSupport()2424 public static boolean getBootDisplayModeSupport() { 2425 return nativeGetBootDisplayModeSupport(); 2426 } 2427 2428 /** There is no associated getter for this method. When this is set, the display is expected 2429 * to start up in this mode next time the device reboots. 2430 * @hide 2431 */ setBootDisplayMode(IBinder displayToken, int displayModeId)2432 public static void setBootDisplayMode(IBinder displayToken, int displayModeId) { 2433 if (displayToken == null) { 2434 throw new IllegalArgumentException("displayToken must not be null"); 2435 } 2436 2437 nativeSetBootDisplayMode(displayToken, displayModeId); 2438 } 2439 2440 /** 2441 * @hide 2442 */ clearBootDisplayMode(IBinder displayToken)2443 public static void clearBootDisplayMode(IBinder displayToken) { 2444 if (displayToken == null) { 2445 throw new IllegalArgumentException("displayToken must not be null"); 2446 } 2447 2448 nativeClearBootDisplayMode(displayToken); 2449 } 2450 2451 /** 2452 * @hide 2453 */ setAutoLowLatencyMode(IBinder displayToken, boolean on)2454 public static void setAutoLowLatencyMode(IBinder displayToken, boolean on) { 2455 if (displayToken == null) { 2456 throw new IllegalArgumentException("displayToken must not be null"); 2457 } 2458 2459 nativeSetAutoLowLatencyMode(displayToken, on); 2460 } 2461 2462 /** 2463 * @hide 2464 */ setGameContentType(IBinder displayToken, boolean on)2465 public static void setGameContentType(IBinder displayToken, boolean on) { 2466 if (displayToken == null) { 2467 throw new IllegalArgumentException("displayToken must not be null"); 2468 } 2469 2470 nativeSetGameContentType(displayToken, on); 2471 } 2472 2473 /** 2474 * Returns whether protected content is supported in GPU composition. 2475 * @hide 2476 */ getProtectedContentSupport()2477 public static boolean getProtectedContentSupport() { 2478 return nativeGetProtectedContentSupport(); 2479 } 2480 2481 /** 2482 * Returns whether brightness operations are supported on a display. 2483 * 2484 * @param displayToken 2485 * The token for the display. 2486 * 2487 * @return Whether brightness operations are supported on the display. 2488 * 2489 * @hide 2490 */ getDisplayBrightnessSupport(IBinder displayToken)2491 public static boolean getDisplayBrightnessSupport(IBinder displayToken) { 2492 return nativeGetDisplayBrightnessSupport(displayToken); 2493 } 2494 2495 /** 2496 * Sets the brightness of a display. 2497 * 2498 * @param displayToken 2499 * The token for the display whose brightness is set. 2500 * @param brightness 2501 * A number between 0.0f (minimum brightness) and 1.0f (maximum brightness), or -1.0f to 2502 * turn the backlight off. 2503 * 2504 * @return Whether the method succeeded or not. 2505 * 2506 * @throws IllegalArgumentException if: 2507 * - displayToken is null; 2508 * - brightness is NaN or greater than 1.0f. 2509 * 2510 * @hide 2511 */ setDisplayBrightness(IBinder displayToken, float brightness)2512 public static boolean setDisplayBrightness(IBinder displayToken, float brightness) { 2513 return setDisplayBrightness(displayToken, brightness, -1, brightness, -1); 2514 } 2515 2516 /** 2517 * Sets the brightness of a display. 2518 * 2519 * @param displayToken 2520 * The token for the display whose brightness is set. 2521 * @param sdrBrightness 2522 * A number between 0.0f (minimum brightness) and 1.0f (maximum brightness), or -1.0f to 2523 * turn the backlight off. Specifies the desired brightness of SDR content. 2524 * @param sdrBrightnessNits 2525 * The value of sdrBrightness converted to calibrated nits. -1 if this isn't available. 2526 * @param displayBrightness 2527 * A number between 0.0f (minimum brightness) and 1.0f (maximum brightness), or 2528 * -1.0f to turn the backlight off. Specifies the desired brightness of the display itself, 2529 * used directly for HDR content. 2530 * @param displayBrightnessNits 2531 * The value of displayBrightness converted to calibrated nits. -1 if this isn't 2532 * available. 2533 * 2534 * @return Whether the method succeeded or not. 2535 * 2536 * @throws IllegalArgumentException if: 2537 * - displayToken is null; 2538 * - brightness is NaN or greater than 1.0f. 2539 * 2540 * @hide 2541 */ setDisplayBrightness(IBinder displayToken, float sdrBrightness, float sdrBrightnessNits, float displayBrightness, float displayBrightnessNits)2542 public static boolean setDisplayBrightness(IBinder displayToken, float sdrBrightness, 2543 float sdrBrightnessNits, float displayBrightness, float displayBrightnessNits) { 2544 Objects.requireNonNull(displayToken); 2545 if (Float.isNaN(displayBrightness) || displayBrightness > 1.0f 2546 || (displayBrightness < 0.0f && displayBrightness != -1.0f)) { 2547 throw new IllegalArgumentException("displayBrightness must be a number between 0.0f " 2548 + " and 1.0f, or -1 to turn the backlight off: " + displayBrightness); 2549 } 2550 if (Float.isNaN(sdrBrightness) || sdrBrightness > 1.0f 2551 || (sdrBrightness < 0.0f && sdrBrightness != -1.0f)) { 2552 throw new IllegalArgumentException("sdrBrightness must be a number between 0.0f " 2553 + "and 1.0f, or -1 to turn the backlight off: " + sdrBrightness); 2554 } 2555 return nativeSetDisplayBrightness(displayToken, sdrBrightness, sdrBrightnessNits, 2556 displayBrightness, displayBrightnessNits); 2557 } 2558 2559 /** 2560 * Creates a mirrored hierarchy for the mirrorOf {@link SurfaceControl} 2561 * 2562 * Real Hierarchy Mirror 2563 * SC (value that's returned) 2564 * | 2565 * A A' 2566 * | | 2567 * B B' 2568 * 2569 * @param mirrorOf The root of the hierarchy that should be mirrored. 2570 * @return A SurfaceControl that's the parent of the root of the mirrored hierarchy. 2571 * 2572 * @hide 2573 */ mirrorSurface(SurfaceControl mirrorOf)2574 public static SurfaceControl mirrorSurface(SurfaceControl mirrorOf) { 2575 long nativeObj = nativeMirrorSurface(mirrorOf.mNativeObject); 2576 SurfaceControl sc = new SurfaceControl(); 2577 sc.mName = mirrorOf.mName + " (mirror)"; 2578 sc.assignNativeObject(nativeObj, "mirrorSurface"); 2579 return sc; 2580 } 2581 validateColorArg(@ize4) float[] color)2582 private static void validateColorArg(@Size(4) float[] color) { 2583 final String msg = "Color must be specified as a float array with" 2584 + " four values to represent r, g, b, a in range [0..1]"; 2585 if (color.length != 4) { 2586 throw new IllegalArgumentException(msg); 2587 } 2588 for (float c:color) { 2589 if ((c < 0.f) || (c > 1.f)) { 2590 throw new IllegalArgumentException(msg); 2591 } 2592 } 2593 } 2594 2595 /** 2596 * Sets the global configuration for all the shadows drawn by SurfaceFlinger. Shadow follows 2597 * material design guidelines. 2598 * 2599 * @param ambientColor Color applied to the ambient shadow. The alpha is premultiplied. A 2600 * float array with four values to represent r, g, b, a in range [0..1] 2601 * @param spotColor Color applied to the spot shadow. The alpha is premultiplied. The position 2602 * of the spot shadow depends on the light position. A float array with 2603 * four values to represent r, g, b, a in range [0..1] 2604 * @param lightPosY Y axis position of the light used to cast the spot shadow in pixels. 2605 * @param lightPosZ Z axis position of the light used to cast the spot shadow in pixels. The X 2606 * axis position is set to the display width / 2. 2607 * @param lightRadius Radius of the light casting the shadow in pixels. 2608 *[ 2609 * @hide 2610 */ setGlobalShadowSettings(@ize4) float[] ambientColor, @Size(4) float[] spotColor, float lightPosY, float lightPosZ, float lightRadius)2611 public static void setGlobalShadowSettings(@Size(4) float[] ambientColor, 2612 @Size(4) float[] spotColor, float lightPosY, float lightPosZ, float lightRadius) { 2613 validateColorArg(ambientColor); 2614 validateColorArg(spotColor); 2615 nativeSetGlobalShadowSettings(ambientColor, spotColor, lightPosY, lightPosZ, lightRadius); 2616 } 2617 2618 /** 2619 * Returns whether/how a display supports DISPLAY_DECORATION. 2620 * 2621 * @param displayToken 2622 * The token for the display. 2623 * 2624 * @return A class describing how the display supports DISPLAY_DECORATION or null if it does 2625 * not. 2626 * 2627 * TODO (b/218524164): Move this out of SurfaceControl. 2628 * @hide 2629 */ getDisplayDecorationSupport(IBinder displayToken)2630 public static DisplayDecorationSupport getDisplayDecorationSupport(IBinder displayToken) { 2631 return nativeGetDisplayDecorationSupport(displayToken); 2632 } 2633 2634 /** 2635 * Adds a callback to be informed about SF's jank classification for a specific surface. 2636 * @hide 2637 */ addJankDataListener(OnJankDataListener listener, SurfaceControl surface)2638 public static void addJankDataListener(OnJankDataListener listener, SurfaceControl surface) { 2639 nativeAddJankDataListener(listener.mNativePtr.get(), surface.mNativeObject); 2640 } 2641 2642 /** 2643 * Removes a jank callback previously added with {@link #addJankDataListener} 2644 * @hide 2645 */ removeJankDataListener(OnJankDataListener listener)2646 public static void removeJankDataListener(OnJankDataListener listener) { 2647 nativeRemoveJankDataListener(listener.mNativePtr.get()); 2648 } 2649 2650 /** 2651 * Return GPU Context priority that is set in SurfaceFlinger's Render Engine. 2652 * @hide 2653 */ getGPUContextPriority()2654 public static int getGPUContextPriority() { 2655 return nativeGetGPUContextPriority(); 2656 } 2657 2658 /** 2659 * Lets surfaceFlinger know the boot procedure is completed. 2660 * @hide 2661 */ bootFinished()2662 public static boolean bootFinished() { 2663 return nativeBootFinished(); 2664 } 2665 2666 /** 2667 * Interface to handle request to 2668 * {@link SurfaceControl.Transaction#addTransactionCommittedListener(Executor, TransactionCommittedListener)} 2669 */ 2670 public interface TransactionCommittedListener { 2671 /** 2672 * Invoked when the transaction has been committed in SurfaceFlinger. 2673 */ onTransactionCommitted()2674 void onTransactionCommitted(); 2675 } 2676 2677 /** 2678 * Transaction stats given to the listener registered in 2679 * {@link SurfaceControl.Transaction#addTransactionCompletedListener} 2680 */ 2681 @FlaggedApi(Flags.FLAG_SDK_DESIRED_PRESENT_TIME) 2682 public static final class TransactionStats { 2683 private long mLatchTimeNanos; 2684 private SyncFence mSyncFence; 2685 2686 // called from native TransactionStats(long latchTimeNanos, long presentFencePtr)2687 private TransactionStats(long latchTimeNanos, long presentFencePtr) { 2688 mLatchTimeNanos = latchTimeNanos; 2689 mSyncFence = new SyncFence(presentFencePtr); 2690 } 2691 2692 /** 2693 * Close the TransactionStats. Called by the framework when the listener returns. 2694 * @hide 2695 */ close()2696 public void close() { 2697 mSyncFence.close(); 2698 } 2699 2700 /** 2701 * Returns the timestamp (in CLOCK_MONOTONIC) of when the frame was latched by the 2702 * framework and queued for presentation. 2703 */ 2704 @FlaggedApi(Flags.FLAG_SDK_DESIRED_PRESENT_TIME) getLatchTimeNanos()2705 public long getLatchTimeNanos() { 2706 return mLatchTimeNanos; 2707 } 2708 2709 /** 2710 * Returns a new SyncFence that signals when the transaction has been presented. 2711 * The caller takes ownership of the fence and is responsible for closing 2712 * it by calling {@link SyncFence#close}. 2713 * If a device does not support present fences, an empty fence will be returned. 2714 */ 2715 @FlaggedApi(Flags.FLAG_SDK_DESIRED_PRESENT_TIME) getPresentFence()2716 public @NonNull SyncFence getPresentFence() { 2717 return new SyncFence(mSyncFence); 2718 } 2719 }; 2720 2721 /** 2722 * Threshold values that are sent with 2723 * {@link Transaction#setTrustedPresentationCallback(SurfaceControl, 2724 * TrustedPresentationThresholds, Executor, Consumer)} 2725 * 2726 * @deprecated Use {@link android.window.TrustedPresentationThresholds} instead. 2727 */ 2728 @Deprecated 2729 public static final class TrustedPresentationThresholds { 2730 private final float mMinAlpha; 2731 private final float mMinFractionRendered; 2732 private final int mStabilityRequirementMs; 2733 2734 /** 2735 * Creates a TrustedPresentationThresholds that's used when calling 2736 * {@link Transaction#setTrustedPresentationCallback(SurfaceControl, 2737 * TrustedPresentationThresholds, Executor, Consumer)} 2738 * 2739 * @param minAlpha The min alpha the {@link SurfaceControl} is required to 2740 * have to be considered inside the threshold. 2741 * @param minFractionRendered The min fraction of the SurfaceControl that was presented 2742 * to the user to be considered inside the threshold. 2743 * @param stabilityRequirementMs The time in milliseconds required for the 2744 * {@link SurfaceControl} to be in the threshold. 2745 * @throws IllegalArgumentException If threshold values are invalid. 2746 */ TrustedPresentationThresholds( @loatRangefrom = 0f, fromInclusive = false, to = 1f) float minAlpha, @FloatRange(from = 0f, fromInclusive = false, to = 1f) float minFractionRendered, @IntRange(from = 1) int stabilityRequirementMs)2747 public TrustedPresentationThresholds( 2748 @FloatRange(from = 0f, fromInclusive = false, to = 1f) float minAlpha, 2749 @FloatRange(from = 0f, fromInclusive = false, to = 1f) float minFractionRendered, 2750 @IntRange(from = 1) int stabilityRequirementMs) { 2751 mMinAlpha = minAlpha; 2752 mMinFractionRendered = minFractionRendered; 2753 mStabilityRequirementMs = stabilityRequirementMs; 2754 2755 checkValid(); 2756 } 2757 checkValid()2758 private void checkValid() { 2759 if (mMinAlpha <= 0 || mMinFractionRendered <= 0 || mStabilityRequirementMs < 1) { 2760 throw new IllegalArgumentException( 2761 "TrustedPresentationThresholds values are invalid"); 2762 } 2763 } 2764 } 2765 2766 /** 2767 * Register a TrustedPresentationCallback for a particular SurfaceControl so it can be notified 2768 * when the specified Threshold has been crossed. 2769 * 2770 * @hide 2771 */ 2772 public abstract static class TrustedPresentationCallback { 2773 private final long mNativeObject; 2774 2775 private static final NativeAllocationRegistry sRegistry = 2776 NativeAllocationRegistry.createMalloced( 2777 TrustedPresentationCallback.class.getClassLoader(), 2778 getNativeTrustedPresentationCallbackFinalizer()); 2779 2780 private final Runnable mFreeNativeResources; 2781 TrustedPresentationCallback()2782 private TrustedPresentationCallback() { 2783 mNativeObject = nativeCreateTpc(this); 2784 mFreeNativeResources = sRegistry.registerNativeAllocation(this, mNativeObject); 2785 } 2786 2787 /** 2788 * Invoked when the SurfaceControl that this TrustedPresentationCallback was registered for 2789 * enters or exits the threshold bounds. 2790 * 2791 * @param inTrustedPresentationState true when the SurfaceControl entered the 2792 * presentation state, false when it has left. 2793 */ onTrustedPresentationChanged(boolean inTrustedPresentationState)2794 public abstract void onTrustedPresentationChanged(boolean inTrustedPresentationState); 2795 } 2796 2797 /** 2798 * An atomic set of changes to a set of SurfaceControl. 2799 */ 2800 public static class Transaction implements Closeable, Parcelable { 2801 /** 2802 * @hide 2803 */ 2804 public static final NativeAllocationRegistry sRegistry = new NativeAllocationRegistry( 2805 Transaction.class.getClassLoader(), 2806 nativeGetNativeTransactionFinalizer(), 512); 2807 /** 2808 * @hide 2809 */ 2810 public long mNativeObject; 2811 2812 private final ArrayMap<SurfaceControl, Point> mResizedSurfaces = new ArrayMap<>(); 2813 private final ArrayMap<SurfaceControl, SurfaceControl> mReparentedSurfaces = 2814 new ArrayMap<>(); 2815 2816 Runnable mFreeNativeResources; 2817 private static final float[] INVALID_COLOR = {-1, -1, -1}; 2818 2819 /** 2820 * @hide 2821 */ checkPreconditions(SurfaceControl sc)2822 protected void checkPreconditions(SurfaceControl sc) { 2823 sc.checkNotReleased(); 2824 } 2825 2826 /** 2827 * Open a new transaction object. The transaction may be filed with commands to 2828 * manipulate {@link SurfaceControl} instances, and then applied atomically with 2829 * {@link #apply}. Eventually the user should invoke {@link #close}, when the object 2830 * is no longer required. Note however that re-using a transaction after a call to apply 2831 * is allowed as a convenience. 2832 */ Transaction()2833 public Transaction() { 2834 this(nativeCreateTransaction()); 2835 } 2836 Transaction(long nativeObject)2837 private Transaction(long nativeObject) { 2838 mNativeObject = nativeObject; 2839 mFreeNativeResources = sRegistry.registerNativeAllocation(this, mNativeObject); 2840 if (!SurfaceControlRegistry.sCallStackDebuggingInitialized) { 2841 SurfaceControlRegistry.initializeCallStackDebugging(); 2842 } 2843 } 2844 Transaction(Parcel in)2845 private Transaction(Parcel in) { 2846 readFromParcel(in); 2847 } 2848 2849 /** 2850 * 2851 * @hide 2852 */ setDefaultApplyToken(IBinder token)2853 public static void setDefaultApplyToken(IBinder token) { 2854 nativeSetDefaultApplyToken(token); 2855 } 2856 2857 /** 2858 * 2859 * @hide 2860 */ getDefaultApplyToken()2861 public static IBinder getDefaultApplyToken() { 2862 return nativeGetDefaultApplyToken(); 2863 } 2864 2865 /** 2866 * Apply the transaction, clearing it's state, and making it usable 2867 * as a new transaction. 2868 */ apply()2869 public void apply() { 2870 apply(/*sync*/ false); 2871 } 2872 2873 /** 2874 * Applies the transaction as a one way binder call. This transaction will be applied out 2875 * of order with other transactions that are applied synchronously. This method is not 2876 * safe. It should only be used when the order does not matter. 2877 * 2878 * @hide 2879 */ applyAsyncUnsafe()2880 public void applyAsyncUnsafe() { 2881 apply(/*sync*/ false, /*oneWay*/ true); 2882 } 2883 2884 2885 /** 2886 * Clear the transaction object, without applying it. 2887 * 2888 * @hide 2889 */ clear()2890 public void clear() { 2891 mResizedSurfaces.clear(); 2892 mReparentedSurfaces.clear(); 2893 if (mNativeObject != 0) { 2894 nativeClearTransaction(mNativeObject); 2895 } 2896 } 2897 2898 /** 2899 * Release the native transaction object, without applying it. 2900 */ 2901 @Override close()2902 public void close() { 2903 mResizedSurfaces.clear(); 2904 mReparentedSurfaces.clear(); 2905 mFreeNativeResources.run(); 2906 mNativeObject = 0; 2907 } 2908 2909 /** 2910 * Jankier version of apply. Avoid use (b/28068298). 2911 * @hide 2912 */ apply(boolean sync)2913 public void apply(boolean sync) { 2914 apply(sync, /*oneWay*/ false); 2915 } 2916 apply(boolean sync, boolean oneWay)2917 private void apply(boolean sync, boolean oneWay) { 2918 applyResizedSurfaces(); 2919 notifyReparentedSurfaces(); 2920 nativeApplyTransaction(mNativeObject, sync, oneWay); 2921 2922 if (SurfaceControlRegistry.sCallStackDebuggingEnabled) { 2923 SurfaceControlRegistry.getProcessInstance().checkCallStackDebugging( 2924 "apply", this, null, null); 2925 } 2926 } 2927 2928 /** 2929 * @hide 2930 */ applyResizedSurfaces()2931 protected void applyResizedSurfaces() { 2932 for (int i = mResizedSurfaces.size() - 1; i >= 0; i--) { 2933 final Point size = mResizedSurfaces.valueAt(i); 2934 final SurfaceControl surfaceControl = mResizedSurfaces.keyAt(i); 2935 synchronized (surfaceControl.mLock) { 2936 surfaceControl.resize(size.x, size.y); 2937 } 2938 } 2939 mResizedSurfaces.clear(); 2940 } 2941 2942 /** 2943 * @hide 2944 */ notifyReparentedSurfaces()2945 protected void notifyReparentedSurfaces() { 2946 final int reparentCount = mReparentedSurfaces.size(); 2947 for (int i = reparentCount - 1; i >= 0; i--) { 2948 final SurfaceControl child = mReparentedSurfaces.keyAt(i); 2949 synchronized (child.mLock) { 2950 final int listenerCount = (child.mReparentListeners != null) 2951 ? child.mReparentListeners.size() : 0; 2952 for (int j = 0; j < listenerCount; j++) { 2953 final OnReparentListener listener = child.mReparentListeners.get(j); 2954 listener.onReparent(this, mReparentedSurfaces.valueAt(i)); 2955 } 2956 mReparentedSurfaces.removeAt(i); 2957 } 2958 } 2959 } 2960 2961 /** 2962 * Toggle the visibility of a given Layer and it's sub-tree. 2963 * 2964 * @param sc The SurfaceControl for which to set the visibility 2965 * @param visible The new visibility 2966 * @return This transaction object. 2967 */ 2968 @NonNull setVisibility(@onNull SurfaceControl sc, boolean visible)2969 public Transaction setVisibility(@NonNull SurfaceControl sc, boolean visible) { 2970 checkPreconditions(sc); 2971 if (visible) { 2972 return show(sc); 2973 } else { 2974 return hide(sc); 2975 } 2976 } 2977 2978 /** 2979 * This information is passed to SurfaceFlinger to decide which window should have a 2980 * priority when deciding about the refresh rate of the display. All windows have the 2981 * lowest priority by default. 2982 * @hide 2983 */ 2984 @NonNull setFrameRateSelectionPriority(@onNull SurfaceControl sc, int priority)2985 public Transaction setFrameRateSelectionPriority(@NonNull SurfaceControl sc, int priority) { 2986 checkPreconditions(sc); 2987 nativeSetFrameRateSelectionPriority(mNativeObject, sc.mNativeObject, priority); 2988 return this; 2989 } 2990 2991 /** 2992 * Request that a given surface and it's sub-tree be shown. 2993 * 2994 * @param sc The surface to show. 2995 * @return This transaction. 2996 * @hide 2997 */ 2998 @UnsupportedAppUsage show(SurfaceControl sc)2999 public Transaction show(SurfaceControl sc) { 3000 checkPreconditions(sc); 3001 if (SurfaceControlRegistry.sCallStackDebuggingEnabled) { 3002 SurfaceControlRegistry.getProcessInstance().checkCallStackDebugging( 3003 "show", this, sc, null); 3004 } 3005 nativeSetFlags(mNativeObject, sc.mNativeObject, 0, SURFACE_HIDDEN); 3006 return this; 3007 } 3008 3009 /** 3010 * Request that a given surface and it's sub-tree be hidden. 3011 * 3012 * @param sc The surface to hidden. 3013 * @return This transaction. 3014 * @hide 3015 */ 3016 @UnsupportedAppUsage hide(SurfaceControl sc)3017 public Transaction hide(SurfaceControl sc) { 3018 checkPreconditions(sc); 3019 if (SurfaceControlRegistry.sCallStackDebuggingEnabled) { 3020 SurfaceControlRegistry.getProcessInstance().checkCallStackDebugging( 3021 "hide", this, sc, null); 3022 } 3023 nativeSetFlags(mNativeObject, sc.mNativeObject, SURFACE_HIDDEN, SURFACE_HIDDEN); 3024 return this; 3025 } 3026 3027 /** 3028 * Sets the SurfaceControl to the specified position relative to the parent 3029 * SurfaceControl 3030 * 3031 * @param sc The SurfaceControl to change position 3032 * @param x the X position 3033 * @param y the Y position 3034 * @return this transaction 3035 */ 3036 @NonNull setPosition(@onNull SurfaceControl sc, float x, float y)3037 public Transaction setPosition(@NonNull SurfaceControl sc, float x, float y) { 3038 checkPreconditions(sc); 3039 if (SurfaceControlRegistry.sCallStackDebuggingEnabled) { 3040 SurfaceControlRegistry.getProcessInstance().checkCallStackDebugging( 3041 "setPosition", this, sc, "x=" + x + " y=" + y); 3042 } 3043 nativeSetPosition(mNativeObject, sc.mNativeObject, x, y); 3044 return this; 3045 } 3046 3047 /** 3048 * Sets the SurfaceControl to the specified scale with (0, 0) as the center point 3049 * of the scale. 3050 * 3051 * @param sc The SurfaceControl to change scale 3052 * @param scaleX the X scale 3053 * @param scaleY the Y scale 3054 * @return this transaction 3055 */ 3056 @NonNull setScale(@onNull SurfaceControl sc, float scaleX, float scaleY)3057 public Transaction setScale(@NonNull SurfaceControl sc, float scaleX, float scaleY) { 3058 checkPreconditions(sc); 3059 Preconditions.checkArgument(scaleX >= 0, "Negative value passed in for scaleX"); 3060 Preconditions.checkArgument(scaleY >= 0, "Negative value passed in for scaleY"); 3061 if (SurfaceControlRegistry.sCallStackDebuggingEnabled) { 3062 SurfaceControlRegistry.getProcessInstance().checkCallStackDebugging( 3063 "setScale", this, sc, "sx=" + scaleX + " sy=" + scaleY); 3064 } 3065 nativeSetScale(mNativeObject, sc.mNativeObject, scaleX, scaleY); 3066 return this; 3067 } 3068 3069 /** 3070 * Set the default buffer size for the SurfaceControl, if there is a 3071 * {@link Surface} associated with the control, then 3072 * this will be the default size for buffers dequeued from it. 3073 * @param sc The surface to set the buffer size for. 3074 * @param w The default width 3075 * @param h The default height 3076 * @return This Transaction 3077 */ 3078 @NonNull setBufferSize(@onNull SurfaceControl sc, @IntRange(from = 0) int w, @IntRange(from = 0) int h)3079 public Transaction setBufferSize(@NonNull SurfaceControl sc, 3080 @IntRange(from = 0) int w, @IntRange(from = 0) int h) { 3081 checkPreconditions(sc); 3082 if (SurfaceControlRegistry.sCallStackDebuggingEnabled) { 3083 SurfaceControlRegistry.getProcessInstance().checkCallStackDebugging( 3084 "setBufferSize", this, sc, "w=" + w + " h=" + h); 3085 } 3086 mResizedSurfaces.put(sc, new Point(w, h)); 3087 return this; 3088 } 3089 3090 /** 3091 * Provide the graphic producer a transform hint if the layer and its children are 3092 * in an orientation different from the display's orientation. The caller is responsible 3093 * for clearing this transform hint if the layer is no longer in a fixed orientation. 3094 * 3095 * The transform hint is used to prevent allocating a buffer of different size when a 3096 * layer is rotated. The producer can choose to consume the hint and allocate the buffer 3097 * with the same size. 3098 * 3099 * @return This Transaction. 3100 * @hide 3101 */ 3102 @NonNull setFixedTransformHint(@onNull SurfaceControl sc, @Surface.Rotation int transformHint)3103 public Transaction setFixedTransformHint(@NonNull SurfaceControl sc, 3104 @Surface.Rotation int transformHint) { 3105 checkPreconditions(sc); 3106 if (SurfaceControlRegistry.sCallStackDebuggingEnabled) { 3107 SurfaceControlRegistry.getProcessInstance().checkCallStackDebugging( 3108 "setFixedTransformHint", this, sc, "hint=" + transformHint); 3109 } 3110 nativeSetFixedTransformHint(mNativeObject, sc.mNativeObject, transformHint); 3111 return this; 3112 } 3113 3114 /** 3115 * Clearing any transform hint if set on this layer. 3116 * 3117 * @return This Transaction. 3118 * @hide 3119 */ 3120 @NonNull unsetFixedTransformHint(@onNull SurfaceControl sc)3121 public Transaction unsetFixedTransformHint(@NonNull SurfaceControl sc) { 3122 checkPreconditions(sc); 3123 if (SurfaceControlRegistry.sCallStackDebuggingEnabled) { 3124 SurfaceControlRegistry.getProcessInstance().checkCallStackDebugging( 3125 "unsetFixedTransformHint", this, sc, null); 3126 } 3127 nativeSetFixedTransformHint(mNativeObject, sc.mNativeObject, -1/* INVALID_ROTATION */); 3128 return this; 3129 } 3130 3131 /** 3132 * Set the Z-order for a given SurfaceControl, relative to it's siblings. 3133 * If two siblings share the same Z order the ordering is undefined. Surfaces 3134 * with a negative Z will be placed below the parent surface. 3135 * 3136 * @param sc The SurfaceControl to set the Z order on 3137 * @param z The Z-order 3138 * @return This Transaction. 3139 */ 3140 @NonNull setLayer(@onNull SurfaceControl sc, @IntRange(from = Integer.MIN_VALUE, to = Integer.MAX_VALUE) int z)3141 public Transaction setLayer(@NonNull SurfaceControl sc, 3142 @IntRange(from = Integer.MIN_VALUE, to = Integer.MAX_VALUE) int z) { 3143 checkPreconditions(sc); 3144 if (SurfaceControlRegistry.sCallStackDebuggingEnabled) { 3145 SurfaceControlRegistry.getProcessInstance().checkCallStackDebugging( 3146 "setLayer", this, sc, "z=" + z); 3147 } 3148 nativeSetLayer(mNativeObject, sc.mNativeObject, z); 3149 return this; 3150 } 3151 3152 /** 3153 * @hide 3154 */ setRelativeLayer(SurfaceControl sc, SurfaceControl relativeTo, int z)3155 public Transaction setRelativeLayer(SurfaceControl sc, SurfaceControl relativeTo, int z) { 3156 checkPreconditions(sc); 3157 if (SurfaceControlRegistry.sCallStackDebuggingEnabled) { 3158 SurfaceControlRegistry.getProcessInstance().checkCallStackDebugging( 3159 "setRelativeLayer", this, sc, "relTo=" + relativeTo + " z=" + z); 3160 } 3161 nativeSetRelativeLayer(mNativeObject, sc.mNativeObject, relativeTo.mNativeObject, z); 3162 return this; 3163 } 3164 3165 /** 3166 * @hide 3167 */ setTransparentRegionHint(SurfaceControl sc, Region transparentRegion)3168 public Transaction setTransparentRegionHint(SurfaceControl sc, Region transparentRegion) { 3169 checkPreconditions(sc); 3170 if (SurfaceControlRegistry.sCallStackDebuggingEnabled) { 3171 SurfaceControlRegistry.getProcessInstance().checkCallStackDebugging( 3172 "unsetFixedTransformHint", this, sc, "region=" + transparentRegion); 3173 } 3174 nativeSetTransparentRegionHint(mNativeObject, 3175 sc.mNativeObject, transparentRegion); 3176 return this; 3177 } 3178 3179 /** 3180 * Set the alpha for a given surface. If the alpha is non-zero the SurfaceControl 3181 * will be blended with the Surfaces under it according to the specified ratio. 3182 * 3183 * @param sc The given SurfaceControl. 3184 * @param alpha The alpha to set. 3185 */ 3186 @NonNull setAlpha(@onNull SurfaceControl sc, @FloatRange(from = 0.0, to = 1.0) float alpha)3187 public Transaction setAlpha(@NonNull SurfaceControl sc, 3188 @FloatRange(from = 0.0, to = 1.0) float alpha) { 3189 checkPreconditions(sc); 3190 if (SurfaceControlRegistry.sCallStackDebuggingEnabled) { 3191 SurfaceControlRegistry.getProcessInstance().checkCallStackDebugging( 3192 "setAlpha", this, sc, "alpha=" + alpha); 3193 } 3194 nativeSetAlpha(mNativeObject, sc.mNativeObject, alpha); 3195 return this; 3196 } 3197 3198 /** 3199 * @hide 3200 */ setInputWindowInfo(SurfaceControl sc, InputWindowHandle handle)3201 public Transaction setInputWindowInfo(SurfaceControl sc, InputWindowHandle handle) { 3202 checkPreconditions(sc); 3203 nativeSetInputWindowInfo(mNativeObject, sc.mNativeObject, handle); 3204 return this; 3205 } 3206 3207 /** 3208 * Adds a callback that is called after WindowInfosListeners from the systems server are 3209 * complete. This is primarily used to ensure that InputDispatcher::setInputWindowsLocked 3210 * has been called before running the added callback. 3211 * 3212 * @hide 3213 */ addWindowInfosReportedListener(@onNull Runnable listener)3214 public Transaction addWindowInfosReportedListener(@NonNull Runnable listener) { 3215 nativeAddWindowInfosReportedListener(mNativeObject, listener); 3216 return this; 3217 } 3218 3219 /** 3220 * Specify how the buffer associated with this Surface is mapped in to the 3221 * parent coordinate space. The source frame will be scaled to fit the destination 3222 * frame, after being rotated according to the orientation parameter. 3223 * 3224 * @param sc The SurfaceControl to specify the geometry of 3225 * @param sourceCrop The source rectangle in buffer space. Or null for the entire buffer. 3226 * @param destFrame The destination rectangle in parent space. Or null for the source frame. 3227 * @param orientation The buffer rotation 3228 * @return This transaction object. 3229 * @deprecated Use {@link #setCrop(SurfaceControl, Rect)}, 3230 * {@link #setBufferTransform(SurfaceControl, int)}, 3231 * {@link #setPosition(SurfaceControl, float, float)} and 3232 * {@link #setScale(SurfaceControl, float, float)} instead. 3233 */ 3234 @NonNull setGeometry(@onNull SurfaceControl sc, @Nullable Rect sourceCrop, @Nullable Rect destFrame, @Surface.Rotation int orientation)3235 public Transaction setGeometry(@NonNull SurfaceControl sc, @Nullable Rect sourceCrop, 3236 @Nullable Rect destFrame, @Surface.Rotation int orientation) { 3237 checkPreconditions(sc); 3238 nativeSetGeometry(mNativeObject, sc.mNativeObject, sourceCrop, destFrame, orientation); 3239 return this; 3240 } 3241 3242 /** 3243 * @hide 3244 */ 3245 @UnsupportedAppUsage setMatrix(SurfaceControl sc, float dsdx, float dtdx, float dtdy, float dsdy)3246 public Transaction setMatrix(SurfaceControl sc, 3247 float dsdx, float dtdx, float dtdy, float dsdy) { 3248 checkPreconditions(sc); 3249 if (SurfaceControlRegistry.sCallStackDebuggingEnabled) { 3250 SurfaceControlRegistry.getProcessInstance().checkCallStackDebugging( 3251 "setMatrix", this, sc, 3252 "dsdx=" + dsdx + " dtdx=" + dtdx + " dtdy=" + dtdy + " dsdy=" + dsdy); 3253 } 3254 nativeSetMatrix(mNativeObject, sc.mNativeObject, 3255 dsdx, dtdx, dtdy, dsdy); 3256 return this; 3257 } 3258 3259 /** 3260 * Sets the transform and position of a {@link SurfaceControl} from a 3x3 transformation 3261 * matrix. 3262 * 3263 * @param sc SurfaceControl to set matrix of 3264 * @param matrix The matrix to apply. 3265 * @param float9 An array of 9 floats to be used to extract the values from the matrix. 3266 * @hide 3267 */ 3268 @UnsupportedAppUsage setMatrix(SurfaceControl sc, Matrix matrix, float[] float9)3269 public Transaction setMatrix(SurfaceControl sc, Matrix matrix, float[] float9) { 3270 matrix.getValues(float9); 3271 setMatrix(sc, float9[MSCALE_X], float9[MSKEW_Y], 3272 float9[MSKEW_X], float9[MSCALE_Y]); 3273 setPosition(sc, float9[MTRANS_X], float9[MTRANS_Y]); 3274 return this; 3275 } 3276 3277 /** 3278 * Sets the color transform for the Surface. 3279 * 3280 * @param sc SurfaceControl to set color transform of 3281 * @param matrix A float array with 9 values represents a 3x3 transform matrix 3282 * @param translation A float array with 3 values represents a translation vector 3283 * @hide 3284 */ setColorTransform(SurfaceControl sc, @Size(9) float[] matrix, @Size(3) float[] translation)3285 public Transaction setColorTransform(SurfaceControl sc, @Size(9) float[] matrix, 3286 @Size(3) float[] translation) { 3287 checkPreconditions(sc); 3288 nativeSetColorTransform(mNativeObject, sc.mNativeObject, matrix, translation); 3289 return this; 3290 } 3291 3292 /** 3293 * Sets the Surface to be color space agnostic. If a surface is color space agnostic, 3294 * the color can be interpreted in any color space. 3295 * @param agnostic A boolean to indicate whether the surface is color space agnostic 3296 * @hide 3297 */ setColorSpaceAgnostic(SurfaceControl sc, boolean agnostic)3298 public Transaction setColorSpaceAgnostic(SurfaceControl sc, boolean agnostic) { 3299 checkPreconditions(sc); 3300 nativeSetColorSpaceAgnostic(mNativeObject, sc.mNativeObject, agnostic); 3301 return this; 3302 } 3303 3304 /** 3305 * Bounds the surface and its children to the bounds specified. Size of the surface will be 3306 * ignored and only the crop and buffer size will be used to determine the bounds of the 3307 * surface. If no crop is specified and the surface has no buffer, the surface bounds is 3308 * only constrained by the size of its parent bounds. 3309 * 3310 * @param sc SurfaceControl to set crop of. 3311 * @param crop Bounds of the crop to apply. 3312 * @hide 3313 * @deprecated Use {@link #setCrop(SurfaceControl, Rect)} instead. 3314 */ 3315 @Deprecated 3316 @UnsupportedAppUsage setWindowCrop(SurfaceControl sc, Rect crop)3317 public Transaction setWindowCrop(SurfaceControl sc, Rect crop) { 3318 checkPreconditions(sc); 3319 if (SurfaceControlRegistry.sCallStackDebuggingEnabled) { 3320 SurfaceControlRegistry.getProcessInstance().checkCallStackDebugging( 3321 "setWindowCrop", this, sc, "crop=" + crop); 3322 } 3323 if (crop != null) { 3324 nativeSetWindowCrop(mNativeObject, sc.mNativeObject, 3325 crop.left, crop.top, crop.right, crop.bottom); 3326 } else { 3327 nativeSetWindowCrop(mNativeObject, sc.mNativeObject, 0, 0, 0, 0); 3328 } 3329 3330 return this; 3331 } 3332 3333 /** 3334 * Bounds the surface and its children to the bounds specified. Size of the surface will be 3335 * ignored and only the crop and buffer size will be used to determine the bounds of the 3336 * surface. If no crop is specified and the surface has no buffer, the surface bounds is 3337 * only constrained by the size of its parent bounds. 3338 * 3339 * @param sc SurfaceControl to set crop of. 3340 * @param crop Bounds of the crop to apply. 3341 * @return this This transaction for chaining 3342 */ setCrop(@onNull SurfaceControl sc, @Nullable Rect crop)3343 public @NonNull Transaction setCrop(@NonNull SurfaceControl sc, @Nullable Rect crop) { 3344 checkPreconditions(sc); 3345 if (SurfaceControlRegistry.sCallStackDebuggingEnabled) { 3346 SurfaceControlRegistry.getProcessInstance().checkCallStackDebugging( 3347 "setCrop", this, sc, "crop=" + crop); 3348 } 3349 if (crop != null) { 3350 Preconditions.checkArgument(crop.isValid(), "Crop " + crop 3351 + " isn't valid"); 3352 nativeSetWindowCrop(mNativeObject, sc.mNativeObject, 3353 crop.left, crop.top, crop.right, crop.bottom); 3354 } else { 3355 nativeSetWindowCrop(mNativeObject, sc.mNativeObject, 0, 0, 0, 0); 3356 } 3357 3358 return this; 3359 } 3360 3361 /** 3362 * Same as {@link Transaction#setWindowCrop(SurfaceControl, Rect)} but sets the crop rect 3363 * top left at 0, 0. 3364 * 3365 * @param sc SurfaceControl to set crop of. 3366 * @param width width of crop rect 3367 * @param height height of crop rect 3368 * @hide 3369 */ setWindowCrop(SurfaceControl sc, int width, int height)3370 public Transaction setWindowCrop(SurfaceControl sc, int width, int height) { 3371 checkPreconditions(sc); 3372 if (SurfaceControlRegistry.sCallStackDebuggingEnabled) { 3373 SurfaceControlRegistry.getProcessInstance().checkCallStackDebugging( 3374 "setWindowCrop", this, sc, "w=" + width + " h=" + height); 3375 } 3376 nativeSetWindowCrop(mNativeObject, sc.mNativeObject, 0, 0, width, height); 3377 return this; 3378 } 3379 3380 /** 3381 * Sets the corner radius of a {@link SurfaceControl}. 3382 * @param sc SurfaceControl 3383 * @param cornerRadius Corner radius in pixels. 3384 * @return Itself. 3385 * @hide 3386 */ 3387 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) setCornerRadius(SurfaceControl sc, float cornerRadius)3388 public Transaction setCornerRadius(SurfaceControl sc, float cornerRadius) { 3389 checkPreconditions(sc); 3390 if (SurfaceControlRegistry.sCallStackDebuggingEnabled) { 3391 SurfaceControlRegistry.getProcessInstance().checkCallStackDebugging( 3392 "setCornerRadius", this, sc, "cornerRadius=" + cornerRadius); 3393 } 3394 nativeSetCornerRadius(mNativeObject, sc.mNativeObject, cornerRadius); 3395 3396 return this; 3397 } 3398 3399 /** 3400 * Sets the background blur radius of the {@link SurfaceControl}. 3401 * 3402 * @param sc SurfaceControl. 3403 * @param radius Blur radius in pixels. 3404 * @return itself. 3405 * @hide 3406 */ setBackgroundBlurRadius(SurfaceControl sc, int radius)3407 public Transaction setBackgroundBlurRadius(SurfaceControl sc, int radius) { 3408 checkPreconditions(sc); 3409 if (SurfaceControlRegistry.sCallStackDebuggingEnabled) { 3410 SurfaceControlRegistry.getProcessInstance().checkCallStackDebugging( 3411 "setBackgroundBlurRadius", this, sc, "radius=" + radius); 3412 } 3413 nativeSetBackgroundBlurRadius(mNativeObject, sc.mNativeObject, radius); 3414 return this; 3415 } 3416 3417 /** 3418 * Specify what regions should be blurred on the {@link SurfaceControl}. 3419 * 3420 * @param sc SurfaceControl. 3421 * @param regions List of regions that will have blurs. 3422 * @return itself. 3423 * @see BlurRegion#toFloatArray() 3424 * @hide 3425 */ setBlurRegions(SurfaceControl sc, float[][] regions)3426 public Transaction setBlurRegions(SurfaceControl sc, float[][] regions) { 3427 checkPreconditions(sc); 3428 nativeSetBlurRegions(mNativeObject, sc.mNativeObject, regions, regions.length); 3429 return this; 3430 } 3431 3432 /** 3433 * @hide 3434 */ setStretchEffect(SurfaceControl sc, float width, float height, float vecX, float vecY, float maxStretchAmountX, float maxStretchAmountY, float childRelativeLeft, float childRelativeTop, float childRelativeRight, float childRelativeBottom)3435 public Transaction setStretchEffect(SurfaceControl sc, float width, float height, 3436 float vecX, float vecY, float maxStretchAmountX, 3437 float maxStretchAmountY, float childRelativeLeft, float childRelativeTop, float childRelativeRight, 3438 float childRelativeBottom) { 3439 checkPreconditions(sc); 3440 nativeSetStretchEffect(mNativeObject, sc.mNativeObject, width, height, 3441 vecX, vecY, maxStretchAmountX, maxStretchAmountY, childRelativeLeft, childRelativeTop, 3442 childRelativeRight, childRelativeBottom); 3443 return this; 3444 } 3445 3446 /** 3447 * @hide 3448 */ 3449 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.O) setLayerStack(SurfaceControl sc, int layerStack)3450 public Transaction setLayerStack(SurfaceControl sc, int layerStack) { 3451 checkPreconditions(sc); 3452 nativeSetLayerStack(mNativeObject, sc.mNativeObject, layerStack); 3453 return this; 3454 } 3455 3456 /** 3457 * Re-parents a given layer to a new parent. Children inherit transform (position, scaling) 3458 * crop, visibility, and Z-ordering from their parents, as if the children were pixels within the 3459 * parent Surface. 3460 * 3461 * @param sc The SurfaceControl to reparent 3462 * @param newParent The new parent for the given control. 3463 * @return This Transaction 3464 */ 3465 @NonNull reparent(@onNull SurfaceControl sc, @Nullable SurfaceControl newParent)3466 public Transaction reparent(@NonNull SurfaceControl sc, 3467 @Nullable SurfaceControl newParent) { 3468 checkPreconditions(sc); 3469 if (SurfaceControlRegistry.sCallStackDebuggingEnabled) { 3470 SurfaceControlRegistry.getProcessInstance().checkCallStackDebugging( 3471 "reparent", this, sc, "newParent=" + newParent); 3472 } 3473 long otherObject = 0; 3474 if (newParent != null) { 3475 newParent.checkNotReleased(); 3476 otherObject = newParent.mNativeObject; 3477 } 3478 nativeReparent(mNativeObject, sc.mNativeObject, otherObject); 3479 mReparentedSurfaces.put(sc, newParent); 3480 return this; 3481 } 3482 3483 /** 3484 * Fills the surface with the specified color. 3485 * @param color A float array with three values to represent r, g, b in range [0..1]. An 3486 * invalid color will remove the color fill. 3487 * @hide 3488 */ 3489 @UnsupportedAppUsage setColor(SurfaceControl sc, @Size(3) float[] color)3490 public Transaction setColor(SurfaceControl sc, @Size(3) float[] color) { 3491 checkPreconditions(sc); 3492 if (SurfaceControlRegistry.sCallStackDebuggingEnabled) { 3493 SurfaceControlRegistry.getProcessInstance().checkCallStackDebugging( 3494 "reparent", this, sc, 3495 "r=" + color[0] + " g=" + color[1] + " b=" + color[2]); 3496 } 3497 nativeSetColor(mNativeObject, sc.mNativeObject, color); 3498 return this; 3499 } 3500 3501 /** 3502 * Removes color fill. 3503 * @hide 3504 */ unsetColor(SurfaceControl sc)3505 public Transaction unsetColor(SurfaceControl sc) { 3506 checkPreconditions(sc); 3507 if (SurfaceControlRegistry.sCallStackDebuggingEnabled) { 3508 SurfaceControlRegistry.getProcessInstance().checkCallStackDebugging( 3509 "unsetColor", this, sc, null); 3510 } 3511 nativeSetColor(mNativeObject, sc.mNativeObject, INVALID_COLOR); 3512 return this; 3513 } 3514 3515 /** 3516 * Sets the security of the surface. Setting the flag is equivalent to creating the 3517 * Surface with the {@link #SECURE} flag. 3518 * @hide 3519 */ setSecure(SurfaceControl sc, boolean isSecure)3520 public Transaction setSecure(SurfaceControl sc, boolean isSecure) { 3521 checkPreconditions(sc); 3522 if (SurfaceControlRegistry.sCallStackDebuggingEnabled) { 3523 SurfaceControlRegistry.getProcessInstance().checkCallStackDebugging( 3524 "setSecure", this, sc, "secure=" + isSecure); 3525 } 3526 if (isSecure) { 3527 nativeSetFlags(mNativeObject, sc.mNativeObject, SECURE, SECURE); 3528 } else { 3529 nativeSetFlags(mNativeObject, sc.mNativeObject, 0, SECURE); 3530 } 3531 return this; 3532 } 3533 3534 /** 3535 * Sets whether the surface should take advantage of display decoration optimizations. 3536 * @hide 3537 */ setDisplayDecoration(SurfaceControl sc, boolean displayDecoration)3538 public Transaction setDisplayDecoration(SurfaceControl sc, boolean displayDecoration) { 3539 checkPreconditions(sc); 3540 if (displayDecoration) { 3541 nativeSetFlags(mNativeObject, sc.mNativeObject, DISPLAY_DECORATION, 3542 DISPLAY_DECORATION); 3543 } else { 3544 nativeSetFlags(mNativeObject, sc.mNativeObject, 0, DISPLAY_DECORATION); 3545 } 3546 return this; 3547 } 3548 3549 /** 3550 * Indicates whether the surface must be considered opaque, even if its pixel format is 3551 * set to translucent. This can be useful if an application needs full RGBA 8888 support 3552 * for instance but will still draw every pixel opaque. 3553 * <p> 3554 * This flag only determines whether opacity will be sampled from the alpha channel. 3555 * Plane-alpha from calls to setAlpha() can still result in blended composition 3556 * regardless of the opaque setting. 3557 * 3558 * Combined effects are (assuming a buffer format with an alpha channel): 3559 * <ul> 3560 * <li>OPAQUE + alpha(1.0) == opaque composition 3561 * <li>OPAQUE + alpha(0.x) == blended composition 3562 * <li>OPAQUE + alpha(0.0) == no composition 3563 * <li>!OPAQUE + alpha(1.0) == blended composition 3564 * <li>!OPAQUE + alpha(0.x) == blended composition 3565 * <li>!OPAQUE + alpha(0.0) == no composition 3566 * </ul> 3567 * If the underlying buffer lacks an alpha channel, it is as if setOpaque(true) 3568 * were set automatically. 3569 * 3570 * @see Builder#setOpaque(boolean) 3571 * 3572 * @param sc The SurfaceControl to update 3573 * @param isOpaque true if the buffer's alpha should be ignored, false otherwise 3574 * @return this 3575 */ 3576 @NonNull setOpaque(@onNull SurfaceControl sc, boolean isOpaque)3577 public Transaction setOpaque(@NonNull SurfaceControl sc, boolean isOpaque) { 3578 checkPreconditions(sc); 3579 if (SurfaceControlRegistry.sCallStackDebuggingEnabled) { 3580 SurfaceControlRegistry.getProcessInstance().checkCallStackDebugging( 3581 "setOpaque", this, sc, "opaque=" + isOpaque); 3582 } 3583 if (isOpaque) { 3584 nativeSetFlags(mNativeObject, sc.mNativeObject, SURFACE_OPAQUE, SURFACE_OPAQUE); 3585 } else { 3586 nativeSetFlags(mNativeObject, sc.mNativeObject, 0, SURFACE_OPAQUE); 3587 } 3588 return this; 3589 } 3590 3591 /** 3592 * @hide 3593 */ setDisplaySurface(IBinder displayToken, Surface surface)3594 public Transaction setDisplaySurface(IBinder displayToken, Surface surface) { 3595 if (displayToken == null) { 3596 throw new IllegalArgumentException("displayToken must not be null"); 3597 } 3598 3599 if (surface != null) { 3600 synchronized (surface.mLock) { 3601 nativeSetDisplaySurface(mNativeObject, displayToken, surface.mNativeObject); 3602 } 3603 } else { 3604 nativeSetDisplaySurface(mNativeObject, displayToken, 0); 3605 } 3606 return this; 3607 } 3608 3609 /** 3610 * @hide 3611 */ setDisplayLayerStack(IBinder displayToken, int layerStack)3612 public Transaction setDisplayLayerStack(IBinder displayToken, int layerStack) { 3613 if (displayToken == null) { 3614 throw new IllegalArgumentException("displayToken must not be null"); 3615 } 3616 nativeSetDisplayLayerStack(mNativeObject, displayToken, layerStack); 3617 return this; 3618 } 3619 3620 /** 3621 * @hide 3622 */ setDisplayFlags(IBinder displayToken, int flags)3623 public Transaction setDisplayFlags(IBinder displayToken, int flags) { 3624 if (displayToken == null) { 3625 throw new IllegalArgumentException("displayToken must not be null"); 3626 } 3627 nativeSetDisplayFlags(mNativeObject, displayToken, flags); 3628 return this; 3629 } 3630 3631 /** 3632 * @hide 3633 */ setDisplayProjection(IBinder displayToken, int orientation, Rect layerStackRect, Rect displayRect)3634 public Transaction setDisplayProjection(IBinder displayToken, 3635 int orientation, Rect layerStackRect, Rect displayRect) { 3636 if (displayToken == null) { 3637 throw new IllegalArgumentException("displayToken must not be null"); 3638 } 3639 if (layerStackRect == null) { 3640 throw new IllegalArgumentException("layerStackRect must not be null"); 3641 } 3642 if (displayRect == null) { 3643 throw new IllegalArgumentException("displayRect must not be null"); 3644 } 3645 nativeSetDisplayProjection(mNativeObject, displayToken, orientation, 3646 layerStackRect.left, layerStackRect.top, layerStackRect.right, layerStackRect.bottom, 3647 displayRect.left, displayRect.top, displayRect.right, displayRect.bottom); 3648 return this; 3649 } 3650 3651 /** 3652 * @hide 3653 */ setDisplaySize(IBinder displayToken, int width, int height)3654 public Transaction setDisplaySize(IBinder displayToken, int width, int height) { 3655 if (displayToken == null) { 3656 throw new IllegalArgumentException("displayToken must not be null"); 3657 } 3658 if (width <= 0 || height <= 0) { 3659 throw new IllegalArgumentException("width and height must be positive"); 3660 } 3661 3662 nativeSetDisplaySize(mNativeObject, displayToken, width, height); 3663 return this; 3664 } 3665 3666 /** flag the transaction as an animation 3667 * @hide 3668 */ setAnimationTransaction()3669 public Transaction setAnimationTransaction() { 3670 nativeSetAnimationTransaction(mNativeObject); 3671 return this; 3672 } 3673 3674 /** 3675 * Provides a hint to SurfaceFlinger to change its offset so that SurfaceFlinger wakes up 3676 * earlier to compose surfaces. The caller should use this as a hint to SurfaceFlinger 3677 * when the scene is complex enough to use GPU composition. The hint will remain active 3678 * until until the client calls {@link Transaction#setEarlyWakeupEnd}. 3679 * 3680 * @hide 3681 */ 3682 @RequiresPermission(Manifest.permission.WAKEUP_SURFACE_FLINGER) setEarlyWakeupStart()3683 public Transaction setEarlyWakeupStart() { 3684 nativeSetEarlyWakeupStart(mNativeObject); 3685 return this; 3686 } 3687 3688 /** 3689 * Removes the early wake up hint set by {@link Transaction#setEarlyWakeupStart}. 3690 * 3691 * @hide 3692 */ 3693 @RequiresPermission(Manifest.permission.WAKEUP_SURFACE_FLINGER) setEarlyWakeupEnd()3694 public Transaction setEarlyWakeupEnd() { 3695 nativeSetEarlyWakeupEnd(mNativeObject); 3696 return this; 3697 } 3698 3699 /** 3700 * @hide 3701 * @return The transaction's current id. 3702 * The id changed every time the transaction is applied. 3703 */ getId()3704 public long getId() { 3705 return nativeGetTransactionId(mNativeObject); 3706 } 3707 3708 /** 3709 * Sets an arbitrary piece of metadata on the surface. This is a helper for int data. 3710 * @hide 3711 */ setMetadata(SurfaceControl sc, int key, int data)3712 public Transaction setMetadata(SurfaceControl sc, int key, int data) { 3713 Parcel parcel = Parcel.obtain(); 3714 parcel.writeInt(data); 3715 try { 3716 setMetadata(sc, key, parcel); 3717 } finally { 3718 parcel.recycle(); 3719 } 3720 return this; 3721 } 3722 3723 /** 3724 * Sets an arbitrary piece of metadata on the surface. 3725 * @hide 3726 */ setMetadata(SurfaceControl sc, int key, Parcel data)3727 public Transaction setMetadata(SurfaceControl sc, int key, Parcel data) { 3728 checkPreconditions(sc); 3729 nativeSetMetadata(mNativeObject, sc.mNativeObject, key, data); 3730 return this; 3731 } 3732 3733 /** 3734 * Draws shadows of length {@code shadowRadius} around the surface {@link SurfaceControl}. 3735 * If the length is 0.0f then the shadows will not be drawn. 3736 * 3737 * Shadows are drawn around the screen bounds, these are the post transformed cropped 3738 * bounds. They can draw over their parent bounds and will be occluded by layers with a 3739 * higher z-order. The shadows will respect the surface's corner radius if the 3740 * rounded corner bounds (transformed source bounds) are within the screen bounds. 3741 * 3742 * A shadow will only be drawn on buffer and color layers. If the radius is applied on a 3743 * container layer, it will be passed down the hierarchy to be applied on buffer and color 3744 * layers but not its children. A scenario where this is useful is when SystemUI animates 3745 * a task by controlling a leash to it, can draw a shadow around the app surface by 3746 * setting a shadow on the leash. This is similar to how rounded corners are set. 3747 * 3748 * @hide 3749 */ setShadowRadius(SurfaceControl sc, float shadowRadius)3750 public Transaction setShadowRadius(SurfaceControl sc, float shadowRadius) { 3751 checkPreconditions(sc); 3752 if (SurfaceControlRegistry.sCallStackDebuggingEnabled) { 3753 SurfaceControlRegistry.getProcessInstance().checkCallStackDebugging( 3754 "setShadowRadius", this, sc, "radius=" + shadowRadius); 3755 } 3756 nativeSetShadowRadius(mNativeObject, sc.mNativeObject, shadowRadius); 3757 return this; 3758 } 3759 3760 /** 3761 * Sets the intended frame rate for this surface. Any switching of refresh rates is 3762 * most probably going to be seamless. 3763 * 3764 * @see #setFrameRate(SurfaceControl, float, int, int) 3765 */ 3766 @NonNull setFrameRate(@onNull SurfaceControl sc, @FloatRange(from = 0.0) float frameRate, @Surface.FrameRateCompatibility int compatibility)3767 public Transaction setFrameRate(@NonNull SurfaceControl sc, 3768 @FloatRange(from = 0.0) float frameRate, 3769 @Surface.FrameRateCompatibility int compatibility) { 3770 return setFrameRate(sc, frameRate, compatibility, 3771 Surface.CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS); 3772 } 3773 3774 /** 3775 * Sets the intended frame rate for the surface {@link SurfaceControl}. 3776 * <p> 3777 * On devices that are capable of running the display at different refresh rates, the system 3778 * may choose a display refresh rate to better match this surface's frame rate. Usage of 3779 * this API won't directly affect the application's frame production pipeline. However, 3780 * because the system may change the display refresh rate, calls to this function may result 3781 * in changes to Choreographer callback timings, and changes to the time interval at which 3782 * the system releases buffers back to the application. 3783 * <p> 3784 * Note that this only has an effect for surfaces presented on the display. If this 3785 * surface is consumed by something other than the system compositor, e.g. a media 3786 * codec, this call has no effect. 3787 * 3788 * @param sc The SurfaceControl to specify the frame rate of. 3789 * @param frameRate The intended frame rate for this surface, in frames per second. 0 is a 3790 * special value that indicates the app will accept the system's choice for 3791 * the display frame rate, which is the default behavior if this function 3792 * isn't called. The <code>frameRate</code> param does <em>not</em> need 3793 * to be a valid refresh rate for this device's display - e.g., it's fine 3794 * to pass 30fps to a device that can only run the display at 60fps. 3795 * @param compatibility The frame rate compatibility of this surface. The compatibility 3796 * value may influence the system's choice of display frame rate. 3797 * This parameter is ignored when <code>frameRate</code> is 0. 3798 * @param changeFrameRateStrategy Whether display refresh rate transitions caused by this 3799 * surface should be seamless. A seamless transition is one 3800 * that doesn't have any visual interruptions, such as a 3801 * black screen for a second or two. This parameter is 3802 * ignored when <code>frameRate</code> is 0. 3803 * @return This transaction object. 3804 * 3805 * @see #clearFrameRate(SurfaceControl) 3806 */ 3807 @NonNull setFrameRate(@onNull SurfaceControl sc, @FloatRange(from = 0.0) float frameRate, @Surface.FrameRateCompatibility int compatibility, @Surface.ChangeFrameRateStrategy int changeFrameRateStrategy)3808 public Transaction setFrameRate(@NonNull SurfaceControl sc, 3809 @FloatRange(from = 0.0) float frameRate, 3810 @Surface.FrameRateCompatibility int compatibility, 3811 @Surface.ChangeFrameRateStrategy int changeFrameRateStrategy) { 3812 checkPreconditions(sc); 3813 nativeSetFrameRate(mNativeObject, sc.mNativeObject, frameRate, compatibility, 3814 changeFrameRateStrategy); 3815 return this; 3816 } 3817 3818 /** 3819 * Clears the frame rate which was set for the surface {@link SurfaceControl}. 3820 * 3821 * <p>This is equivalent to calling {@link #setFrameRate(SurfaceControl, float, int, int)} 3822 * using {@code 0} for {@code frameRate}. 3823 * <p> 3824 * Note that this only has an effect for surfaces presented on the display. If this 3825 * surface is consumed by something other than the system compositor, e.g. a media 3826 * codec, this call has no effect. 3827 * 3828 * @param sc The SurfaceControl to clear the frame rate of. 3829 * @return This transaction object. 3830 * 3831 * @see #setFrameRate(SurfaceControl, float, int) 3832 */ 3833 @NonNull clearFrameRate(@onNull SurfaceControl sc)3834 public Transaction clearFrameRate(@NonNull SurfaceControl sc) { 3835 checkPreconditions(sc); 3836 nativeSetFrameRate(mNativeObject, sc.mNativeObject, 0.0f, 3837 Surface.FRAME_RATE_COMPATIBILITY_DEFAULT, 3838 Surface.CHANGE_FRAME_RATE_ALWAYS); 3839 return this; 3840 } 3841 3842 /** 3843 * Sets the default frame rate compatibility for the surface {@link SurfaceControl} 3844 * 3845 * @param sc The SurfaceControl to specify the frame rate of. 3846 * @param compatibility The frame rate compatibility of this surface. The compatibility 3847 * value may influence the system's choice of display frame rate. 3848 * 3849 * @return This transaction object. 3850 * 3851 * @hide 3852 */ 3853 @NonNull setDefaultFrameRateCompatibility(@onNull SurfaceControl sc, @Surface.FrameRateCompatibility int compatibility)3854 public Transaction setDefaultFrameRateCompatibility(@NonNull SurfaceControl sc, 3855 @Surface.FrameRateCompatibility int compatibility) { 3856 checkPreconditions(sc); 3857 nativeSetDefaultFrameRateCompatibility(mNativeObject, sc.mNativeObject, compatibility); 3858 return this; 3859 } 3860 3861 /** 3862 * Sets the frame rate category for the {@link SurfaceControl}. 3863 * 3864 * This helps instruct the system on choosing a display refresh rate based on the surface's 3865 * chosen category, which is a device-specific range of frame rates. 3866 * {@link #setFrameRateCategory} should be used by components such as animations that do not 3867 * require an exact frame rate, but has an opinion on an approximate desirable frame rate. 3868 * The values of {@code category} gives example use cases for which category to choose. 3869 * 3870 * To instead specify an exact frame rate, use 3871 * {@link #setFrameRate(SurfaceControl, float, int, int)}, which is more suitable for 3872 * content that knows specifically which frame rate is optimal. 3873 * Although not a common use case, {@link #setFrameRateCategory} and {@link #setFrameRate} 3874 * can be called together, with both calls potentially influencing the display refresh rate. 3875 * For example, considering only one {@link SurfaceControl}: if {@link #setFrameRate}'s 3876 * value is 24 and {@link #setFrameRateCategory}'s value is 3877 * {@link Surface#FRAME_RATE_CATEGORY_HIGH}, defined to be the range [90,120] fps for an 3878 * example device, then the best refresh rate for the SurfaceControl should be 120 fps. 3879 * This is because 120 fps is a multiple of 24 fps, and 120 fps is in the specified 3880 * category's range. 3881 * 3882 * @param sc The SurfaceControl to specify the frame rate category of. 3883 * @param category The frame rate category of this surface. The category value may influence 3884 * the system's choice of display frame rate. 3885 * @param smoothSwitchOnly Set to {@code true} to indicate the display frame rate should not 3886 * change if changing it would cause jank. Else {@code false}. 3887 * This parameter is ignored when {@code category} is 3888 * {@link Surface#FRAME_RATE_CATEGORY_DEFAULT}. 3889 * 3890 * @return This transaction object. 3891 * 3892 * @see #setFrameRate(SurfaceControl, float, int, int) 3893 * 3894 * @hide 3895 */ 3896 @NonNull setFrameRateCategory(@onNull SurfaceControl sc, @Surface.FrameRateCategory int category, boolean smoothSwitchOnly)3897 public Transaction setFrameRateCategory(@NonNull SurfaceControl sc, 3898 @Surface.FrameRateCategory int category, boolean smoothSwitchOnly) { 3899 checkPreconditions(sc); 3900 nativeSetFrameRateCategory(mNativeObject, sc.mNativeObject, category, smoothSwitchOnly); 3901 return this; 3902 } 3903 3904 /** 3905 * Sets the frame rate selection strategy for the {@link SurfaceControl}. 3906 * 3907 * This instructs the system on how to choose a display refresh rate, following the 3908 * strategy for the layer's frame rate specifications relative to other layers'. 3909 * 3910 * @param sc The SurfaceControl to specify the frame rate category of. 3911 * @param strategy The frame rate selection strategy. 3912 * 3913 * @return This transaction object. 3914 * 3915 * @see #setFrameRate(SurfaceControl, float, int, int) 3916 * @see #setFrameRateCategory(SurfaceControl, int) 3917 * @see #setDefaultFrameRateCompatibility(SurfaceControl, int) 3918 * 3919 * @hide 3920 */ 3921 @NonNull setFrameRateSelectionStrategy( @onNull SurfaceControl sc, @FrameRateSelectionStrategy int strategy)3922 public Transaction setFrameRateSelectionStrategy( 3923 @NonNull SurfaceControl sc, @FrameRateSelectionStrategy int strategy) { 3924 checkPreconditions(sc); 3925 nativeSetFrameRateSelectionStrategy(mNativeObject, sc.mNativeObject, strategy); 3926 return this; 3927 } 3928 3929 /** 3930 * Sets focus on the window identified by the input {@code token} if the window is focusable 3931 * otherwise the request is dropped. 3932 * 3933 * If the window is not visible, the request will be queued until the window becomes 3934 * visible or the request is overrriden by another request. The currently focused window 3935 * will lose focus immediately. This is to send the newly focused window any focus 3936 * dispatched events that occur while it is completing its first draw. 3937 * 3938 * @hide 3939 */ setFocusedWindow(@onNull IBinder token, String windowName, int displayId)3940 public Transaction setFocusedWindow(@NonNull IBinder token, String windowName, 3941 int displayId) { 3942 nativeSetFocusedWindow(mNativeObject, token, windowName, displayId); 3943 return this; 3944 } 3945 3946 /** 3947 * Removes the input focus from the current window which is having the input focus. Should 3948 * only be called when the current focused app is not responding and the current focused 3949 * window is not beloged to the current focused app. 3950 * @hide 3951 */ removeCurrentInputFocus(int displayId)3952 public Transaction removeCurrentInputFocus(int displayId) { 3953 nativeRemoveCurrentInputFocus(mNativeObject, displayId); 3954 return this; 3955 } 3956 3957 /** 3958 * Adds or removes the flag SKIP_SCREENSHOT of the surface. Setting the flag is equivalent 3959 * to creating the Surface with the {@link #SKIP_SCREENSHOT} flag. 3960 * 3961 * @hide 3962 */ setSkipScreenshot(SurfaceControl sc, boolean skipScrenshot)3963 public Transaction setSkipScreenshot(SurfaceControl sc, boolean skipScrenshot) { 3964 checkPreconditions(sc); 3965 if (skipScrenshot) { 3966 nativeSetFlags(mNativeObject, sc.mNativeObject, SKIP_SCREENSHOT, SKIP_SCREENSHOT); 3967 } else { 3968 nativeSetFlags(mNativeObject, sc.mNativeObject, 0, SKIP_SCREENSHOT); 3969 } 3970 return this; 3971 } 3972 3973 /** 3974 * Set a buffer for a SurfaceControl. This can only be used for SurfaceControls that were 3975 * created as type {@link #FX_SURFACE_BLAST} 3976 * 3977 * @hide 3978 * @deprecated Use {@link #setBuffer(SurfaceControl, HardwareBuffer)} instead 3979 */ 3980 @Deprecated setBuffer(SurfaceControl sc, GraphicBuffer buffer)3981 public Transaction setBuffer(SurfaceControl sc, GraphicBuffer buffer) { 3982 return setBuffer(sc, HardwareBuffer.createFromGraphicBuffer(buffer)); 3983 } 3984 3985 /** 3986 * Updates the HardwareBuffer displayed for the SurfaceControl. 3987 * 3988 * Note that the buffer must be allocated with {@link HardwareBuffer#USAGE_COMPOSER_OVERLAY} 3989 * as well as {@link HardwareBuffer#USAGE_GPU_SAMPLED_IMAGE} as the surface control might 3990 * be composited using either an overlay or using the GPU. 3991 * 3992 * @param sc The SurfaceControl to update 3993 * @param buffer The buffer to be displayed 3994 * @return this 3995 */ setBuffer(@onNull SurfaceControl sc, @Nullable HardwareBuffer buffer)3996 public @NonNull Transaction setBuffer(@NonNull SurfaceControl sc, 3997 @Nullable HardwareBuffer buffer) { 3998 return setBuffer(sc, buffer, null); 3999 } 4000 4001 /** 4002 * Unsets the buffer for the SurfaceControl in the current Transaction. This will not clear 4003 * the buffer being rendered, but resets the buffer state in the Transaction only. The call 4004 * will also invoke the release callback. 4005 * 4006 * Note, this call is different from passing a null buffer to 4007 * {@link SurfaceControl.Transaction#setBuffer} which will release the last displayed 4008 * buffer. 4009 * 4010 * @hide 4011 */ unsetBuffer(SurfaceControl sc)4012 public Transaction unsetBuffer(SurfaceControl sc) { 4013 nativeUnsetBuffer(mNativeObject, sc.mNativeObject); 4014 return this; 4015 } 4016 4017 /** 4018 * Updates the HardwareBuffer displayed for the SurfaceControl. 4019 * 4020 * Note that the buffer must be allocated with {@link HardwareBuffer#USAGE_COMPOSER_OVERLAY} 4021 * as well as {@link HardwareBuffer#USAGE_GPU_SAMPLED_IMAGE} as the surface control might 4022 * be composited using either an overlay or using the GPU. 4023 * 4024 * A presentation fence may be passed to improve performance by allowing the buffer 4025 * to complete rendering while it is waiting for the transaction to be applied. 4026 * For example, if the buffer is being produced by rendering with OpenGL ES then 4027 * a fence created with 4028 * {@link android.opengl.EGLExt#eglDupNativeFenceFDANDROID(EGLDisplay, EGLSync)} can be 4029 * used to allow the GPU rendering to be concurrent with the transaction. The compositor 4030 * will wait for the fence to be signaled before the buffer is displayed. If multiple 4031 * buffers are set as part of the same transaction, the presentation fences of all of them 4032 * must signal before any buffer is displayed. That is, the entire transaction is delayed 4033 * until all presentation fences have signaled, ensuring the transaction remains consistent. 4034 * 4035 * @param sc The SurfaceControl to update 4036 * @param buffer The buffer to be displayed. Pass in a null buffer to release the last 4037 * displayed buffer. 4038 * @param fence The presentation fence. If null or invalid, this is equivalent to 4039 * {@link #setBuffer(SurfaceControl, HardwareBuffer)} 4040 * @return this 4041 */ setBuffer(@onNull SurfaceControl sc, @Nullable HardwareBuffer buffer, @Nullable SyncFence fence)4042 public @NonNull Transaction setBuffer(@NonNull SurfaceControl sc, 4043 @Nullable HardwareBuffer buffer, @Nullable SyncFence fence) { 4044 return setBuffer(sc, buffer, fence, null); 4045 } 4046 4047 /** 4048 * Updates the HardwareBuffer displayed for the SurfaceControl. 4049 * 4050 * Note that the buffer must be allocated with {@link HardwareBuffer#USAGE_COMPOSER_OVERLAY} 4051 * as well as {@link HardwareBuffer#USAGE_GPU_SAMPLED_IMAGE} as the surface control might 4052 * be composited using either an overlay or using the GPU. 4053 * 4054 * A presentation fence may be passed to improve performance by allowing the buffer 4055 * to complete rendering while it is waiting for the transaction to be applied. 4056 * For example, if the buffer is being produced by rendering with OpenGL ES then 4057 * a fence created with 4058 * {@link android.opengl.EGLExt#eglDupNativeFenceFDANDROID(EGLDisplay, EGLSync)} can be 4059 * used to allow the GPU rendering to be concurrent with the transaction. The compositor 4060 * will wait for the fence to be signaled before the buffer is displayed. If multiple 4061 * buffers are set as part of the same transaction, the presentation fences of all of them 4062 * must signal before any buffer is displayed. That is, the entire transaction is delayed 4063 * until all presentation fences have signaled, ensuring the transaction remains consistent. 4064 * 4065 * A releaseCallback may be passed to know when the buffer is safe to be reused. This 4066 * is recommended when attempting to render continuously using SurfaceControl transactions 4067 * instead of through {@link Surface}, as it provides a safe & reliable way to know when 4068 * a buffer can be re-used. The callback will be invoked with a {@link SyncFence} which, 4069 * if {@link SyncFence#isValid() valid}, must be waited on prior to using the buffer. This 4070 * can either be done directly with {@link SyncFence#awaitForever()} or it may be done 4071 * indirectly such as passing it as a release fence to 4072 * {@link android.media.Image#setFence(SyncFence)} when using 4073 * {@link android.media.ImageReader}. 4074 * 4075 * @param sc The SurfaceControl to update 4076 * @param buffer The buffer to be displayed 4077 * @param fence The presentation fence. If null or invalid, this is equivalent to 4078 * {@link #setBuffer(SurfaceControl, HardwareBuffer)} 4079 * @param releaseCallback The callback to invoke when the buffer being set has been released 4080 * by a later transaction. That is, the point at which it is safe 4081 * to re-use the buffer. 4082 * @return this 4083 */ setBuffer(@onNull SurfaceControl sc, @Nullable HardwareBuffer buffer, @Nullable SyncFence fence, @Nullable Consumer<SyncFence> releaseCallback)4084 public @NonNull Transaction setBuffer(@NonNull SurfaceControl sc, 4085 @Nullable HardwareBuffer buffer, @Nullable SyncFence fence, 4086 @Nullable Consumer<SyncFence> releaseCallback) { 4087 checkPreconditions(sc); 4088 if (fence != null) { 4089 synchronized (fence.getLock()) { 4090 nativeSetBuffer(mNativeObject, sc.mNativeObject, buffer, 4091 fence.getNativeFence(), releaseCallback); 4092 } 4093 } else { 4094 nativeSetBuffer(mNativeObject, sc.mNativeObject, buffer, 0, releaseCallback); 4095 } 4096 return this; 4097 } 4098 4099 4100 /** 4101 * Sets the buffer transform that should be applied to the current buffer. 4102 * 4103 * This can be used in combination with 4104 * {@link AttachedSurfaceControl#addOnBufferTransformHintChangedListener(AttachedSurfaceControl.OnBufferTransformHintChangedListener)} 4105 * to pre-rotate the buffer for the current display orientation. This can 4106 * improve the performance of displaying the associated buffer. 4107 * 4108 * @param sc The SurfaceControl to update 4109 * @param transform The transform to apply to the buffer. 4110 * @return this 4111 */ setBufferTransform(@onNull SurfaceControl sc, @SurfaceControl.BufferTransform int transform)4112 public @NonNull Transaction setBufferTransform(@NonNull SurfaceControl sc, 4113 @SurfaceControl.BufferTransform int transform) { 4114 checkPreconditions(sc); 4115 nativeSetBufferTransform(mNativeObject, sc.mNativeObject, transform); 4116 return this; 4117 } 4118 4119 /** 4120 * Updates the region for the content on this surface updated in this transaction. The 4121 * damage region is the area of the buffer that has changed since the previously 4122 * sent buffer. This can be used to reduce the amount of recomposition that needs 4123 * to happen when only a small region of the buffer is being updated, such as for 4124 * a small blinking cursor or a loading indicator. 4125 * 4126 * @param sc The SurfaceControl on which to set the damage region 4127 * @param region The region to set. If null, the entire buffer is assumed dirty. This is 4128 * equivalent to not setting a damage region at all. 4129 */ setDamageRegion(@onNull SurfaceControl sc, @Nullable Region region)4130 public @NonNull Transaction setDamageRegion(@NonNull SurfaceControl sc, 4131 @Nullable Region region) { 4132 nativeSetDamageRegion(mNativeObject, sc.mNativeObject, region); 4133 return this; 4134 } 4135 4136 /** 4137 * Set if the layer can be dimmed. 4138 * 4139 * <p>Dimming is to adjust brightness of the layer. 4140 * Default value is {@code true}, which means the layer can be dimmed. 4141 * Disabling dimming means the brightness of the layer can not be changed, i.e., 4142 * keep the white point for the layer same as the display brightness.</p> 4143 * 4144 * @param sc The SurfaceControl on which to enable or disable dimming. 4145 * @param dimmingEnabled The dimming flag. 4146 * @return this. 4147 * 4148 * @hide 4149 */ setDimmingEnabled(@onNull SurfaceControl sc, boolean dimmingEnabled)4150 public @NonNull Transaction setDimmingEnabled(@NonNull SurfaceControl sc, 4151 boolean dimmingEnabled) { 4152 checkPreconditions(sc); 4153 nativeSetDimmingEnabled(mNativeObject, sc.mNativeObject, dimmingEnabled); 4154 return this; 4155 } 4156 4157 /** 4158 * Set the color space for the SurfaceControl. The supported color spaces are SRGB 4159 * and Display P3, other color spaces will be treated as SRGB. This can only be used for 4160 * SurfaceControls that were created as type {@link #FX_SURFACE_BLAST} 4161 * 4162 * @hide 4163 * @deprecated use {@link #setDataSpace(SurfaceControl, long)} instead 4164 */ 4165 @Deprecated setColorSpace(SurfaceControl sc, ColorSpace colorSpace)4166 public Transaction setColorSpace(SurfaceControl sc, ColorSpace colorSpace) { 4167 checkPreconditions(sc); 4168 if (colorSpace.getId() == ColorSpace.Named.DISPLAY_P3.ordinal()) { 4169 setDataSpace(sc, DataSpace.DATASPACE_DISPLAY_P3); 4170 } else { 4171 setDataSpace(sc, DataSpace.DATASPACE_SRGB); 4172 } 4173 return this; 4174 } 4175 4176 /** 4177 * Set the dataspace for the SurfaceControl. This will control how the buffer 4178 * set with {@link #setBuffer(SurfaceControl, HardwareBuffer)} is displayed. 4179 * 4180 * @param sc The SurfaceControl to update 4181 * @param dataspace The dataspace to set it to 4182 * @return this 4183 */ setDataSpace(@onNull SurfaceControl sc, @DataSpace.NamedDataSpace int dataspace)4184 public @NonNull Transaction setDataSpace(@NonNull SurfaceControl sc, 4185 @DataSpace.NamedDataSpace int dataspace) { 4186 checkPreconditions(sc); 4187 nativeSetDataSpace(mNativeObject, sc.mNativeObject, dataspace); 4188 return this; 4189 } 4190 4191 /** 4192 * Sets the desired extended range brightness for the layer. This only applies for layers 4193 * whose dataspace has RANGE_EXTENDED. 4194 * 4195 * @param sc The layer whose extended range brightness is being specified 4196 * @param currentBufferRatio The current HDR/SDR ratio of the current buffer. For example 4197 * if the buffer was rendered with a target SDR whitepoint of 4198 * 100 nits and a max display brightness of 200 nits, this should 4199 * be set to 2.0f. 4200 * 4201 * <p>Default value is 1.0f. 4202 * 4203 * <p>Transfer functions that encode their own brightness ranges, 4204 * such as HLG or PQ, should also set this to 1.0f and instead 4205 * communicate extended content brightness information via 4206 * metadata such as CTA861_3 or SMPTE2086. 4207 * 4208 * <p>Must be finite && >= 1.0f 4209 * 4210 * @param desiredRatio The desired HDR/SDR ratio. This can be used to communicate the max 4211 * desired brightness range. This is similar to the "max luminance" 4212 * value in other HDR metadata formats, but represented as a ratio of 4213 * the target SDR whitepoint to the max display brightness. The system 4214 * may not be able to, or may choose not to, deliver the 4215 * requested range. 4216 * 4217 * <p>While requesting a large desired ratio will result in the most 4218 * dynamic range, voluntarily reducing the requested range can help 4219 * improve battery life as well as can improve quality by ensuring 4220 * greater bit depth is allocated to the luminance range in use. 4221 * 4222 * <p>Default value is 1.0f and indicates that extended range brightness 4223 * is not being used, so the resulting SDR or HDR behavior will be 4224 * determined entirely by the dataspace being used (ie, typically SDR 4225 * however PQ or HLG transfer functions will still result in HDR) 4226 * 4227 * <p>Must be finite && >= 1.0f 4228 * @return this 4229 **/ setExtendedRangeBrightness(@onNull SurfaceControl sc, float currentBufferRatio, float desiredRatio)4230 public @NonNull Transaction setExtendedRangeBrightness(@NonNull SurfaceControl sc, 4231 float currentBufferRatio, float desiredRatio) { 4232 checkPreconditions(sc); 4233 if (!Float.isFinite(currentBufferRatio) || currentBufferRatio < 1.0f) { 4234 throw new IllegalArgumentException( 4235 "currentBufferRatio must be finite && >= 1.0f; got " + currentBufferRatio); 4236 } 4237 if (!Float.isFinite(desiredRatio) || desiredRatio < 1.0f) { 4238 throw new IllegalArgumentException( 4239 "desiredRatio must be finite && >= 1.0f; got " + desiredRatio); 4240 } 4241 nativeSetExtendedRangeBrightness(mNativeObject, sc.mNativeObject, currentBufferRatio, 4242 desiredRatio); 4243 return this; 4244 } 4245 4246 /** 4247 * Sets the desired HDR headroom for the layer. 4248 * 4249 * <p>Prefer using this API over {@link #setExtendedRangeBrightness} for formats that 4250 *. conform to HDR video standards like HLG or HDR10 which do not communicate a HDR/SDR 4251 * ratio as part of generating the buffer. 4252 * 4253 * @param sc The layer whose desired HDR headroom is being specified 4254 * 4255 * @param desiredRatio The desired HDR/SDR ratio. This can be used to communicate the max 4256 * desired brightness range. This is similar to the "max luminance" 4257 * value in other HDR metadata formats, but represented as a ratio of 4258 * the target SDR whitepoint to the max display brightness. The system 4259 * may not be able to, or may choose not to, deliver the 4260 * requested range. 4261 * 4262 * <p>Default value is 0.0f and indicates that the system will choose 4263 * the best headroom for this surface control's content. Typically, 4264 * this means that HLG/PQ encoded content will be displayed with some 4265 * HDR headroom greater than 1.0. 4266 * 4267 * <p>When called after {@link #setExtendedRangeBrightness}, the 4268 * desiredHeadroom will override the desiredRatio provided by 4269 * {@link #setExtendedRangeBrightness}. Conversely, when called 4270 * before {@link #setExtendedRangeBrightness}, the desiredRatio provided 4271 * by {@link #setExtendedRangeBrightness} will override the 4272 * desiredHeadroom. 4273 * 4274 * <p>Must be finite && >= 1.0f or 0.0f. 4275 * @return this 4276 * @see #setExtendedRangeBrightness 4277 **/ 4278 @FlaggedApi(com.android.graphics.hwui.flags.Flags.FLAG_LIMITED_HDR) setDesiredHdrHeadroom(@onNull SurfaceControl sc, @FloatRange(from = 0.0f) float desiredRatio)4279 public @NonNull Transaction setDesiredHdrHeadroom(@NonNull SurfaceControl sc, 4280 @FloatRange(from = 0.0f) float desiredRatio) { 4281 checkPreconditions(sc); 4282 if (!Float.isFinite(desiredRatio) || (desiredRatio != 0 && desiredRatio < 1.0f)) { 4283 throw new IllegalArgumentException( 4284 "desiredRatio must be finite && >= 1.0f or 0; got " + desiredRatio); 4285 } 4286 nativeSetDesiredHdrHeadroom(mNativeObject, sc.mNativeObject, desiredRatio); 4287 return this; 4288 } 4289 4290 /** 4291 * Sets the caching hint for the layer. By default, the caching hint is 4292 * {@link CACHING_ENABLED}. 4293 * 4294 * @param sc The SurfaceControl to update 4295 * @param cachingHint The caching hint to apply to the SurfaceControl. The CachingHint is 4296 * not applied to any children of this SurfaceControl. 4297 * @return this 4298 * @hide 4299 */ setCachingHint( @onNull SurfaceControl sc, @CachingHint int cachingHint)4300 public @NonNull Transaction setCachingHint( 4301 @NonNull SurfaceControl sc, @CachingHint int cachingHint) { 4302 checkPreconditions(sc); 4303 nativeSetCachingHint(mNativeObject, sc.mNativeObject, cachingHint); 4304 return this; 4305 } 4306 4307 /** 4308 * @see Transaction#setTrustedOverlay(SurfaceControl, int) 4309 * @hide 4310 */ setTrustedOverlay(SurfaceControl sc, boolean isTrustedOverlay)4311 public Transaction setTrustedOverlay(SurfaceControl sc, boolean isTrustedOverlay) { 4312 return setTrustedOverlay(sc, 4313 isTrustedOverlay ? TrustedOverlay.ENABLED : TrustedOverlay.UNSET); 4314 } 4315 4316 /** 4317 * Trusted overlay state prevents SurfaceControl from being considered as obscuring for 4318 * input occlusion detection purposes. The caller must hold the 4319 * ACCESS_SURFACE_FLINGER permission. See {@code TrustedOverlay}. 4320 * <p> 4321 * Arguments: 4322 * {@code TrustedOverlay.UNSET} - The default value, SurfaceControl will inherit the state 4323 * from its parents. If the parent state is also {@code TrustedOverlay.UNSET}, the layer 4324 * will be considered as untrusted. 4325 * <p> 4326 * {@code TrustedOverlay.DISABLED} - Treats this SurfaceControl and all its children as an 4327 * untrusted overlay. This will override any state set by its parent SurfaceControl. 4328 * <p> 4329 * {@code TrustedOverlay.ENABLED} - Treats this SurfaceControl and all its children as a 4330 * trusted overlay unless the child SurfaceControl explicitly disables its trusted state 4331 * via {@code TrustedOverlay.DISABLED}. 4332 * <p> 4333 * @hide 4334 */ setTrustedOverlay(SurfaceControl sc, @TrustedOverlay int trustedOverlay)4335 public Transaction setTrustedOverlay(SurfaceControl sc, 4336 @TrustedOverlay int trustedOverlay) { 4337 checkPreconditions(sc); 4338 nativeSetTrustedOverlay(mNativeObject, sc.mNativeObject, trustedOverlay); 4339 return this; 4340 } 4341 4342 /** 4343 * Sets the input event drop mode on this SurfaceControl and its children. The caller must 4344 * hold the ACCESS_SURFACE_FLINGER permission. See {@code InputEventDropMode}. 4345 * @hide 4346 */ setDropInputMode(SurfaceControl sc, @DropInputMode int mode)4347 public Transaction setDropInputMode(SurfaceControl sc, @DropInputMode int mode) { 4348 checkPreconditions(sc); 4349 nativeSetDropInputMode(mNativeObject, sc.mNativeObject, mode); 4350 return this; 4351 } 4352 4353 /** 4354 * Sets a property on this SurfaceControl and all its children indicating that the visible 4355 * region of this SurfaceControl should be considered when computing TrustedPresentation 4356 * Thresholds. 4357 * <p> 4358 * API Guidance: 4359 * The goal of this API is to identify windows that can be used to occlude content on 4360 * another window. This includes windows controlled by the user or the system. If the window 4361 * is transient, like Toast or notification shade, the window should not set this flag since 4362 * the user or the app cannot use the window to occlude content in a persistent manner. All 4363 * apps should have this flag set. 4364 * <p> 4365 * The caller must hold the ACCESS_SURFACE_FLINGER permission. 4366 * @hide 4367 */ setCanOccludePresentation(SurfaceControl sc, boolean canOccludePresentation)4368 public Transaction setCanOccludePresentation(SurfaceControl sc, 4369 boolean canOccludePresentation) { 4370 checkPreconditions(sc); 4371 final int value = (canOccludePresentation) ? CAN_OCCLUDE_PRESENTATION : 0; 4372 nativeSetFlags(mNativeObject, sc.mNativeObject, value, CAN_OCCLUDE_PRESENTATION); 4373 return this; 4374 } 4375 4376 /** 4377 * Sends a flush jank data transaction for the given surface. 4378 * @hide 4379 */ sendSurfaceFlushJankData(SurfaceControl sc)4380 public static void sendSurfaceFlushJankData(SurfaceControl sc) { 4381 sc.checkNotReleased(); 4382 nativeSurfaceFlushJankData(sc.mNativeObject); 4383 } 4384 4385 /** 4386 * @hide 4387 */ sanitize(int pid, int uid)4388 public void sanitize(int pid, int uid) { 4389 nativeSanitize(mNativeObject, pid, uid); 4390 } 4391 4392 /** 4393 * @hide 4394 */ setDesintationFrame(SurfaceControl sc, @NonNull Rect destinationFrame)4395 public Transaction setDesintationFrame(SurfaceControl sc, @NonNull Rect destinationFrame) { 4396 checkPreconditions(sc); 4397 nativeSetDestinationFrame(mNativeObject, sc.mNativeObject, 4398 destinationFrame.left, destinationFrame.top, destinationFrame.right, 4399 destinationFrame.bottom); 4400 return this; 4401 } 4402 4403 /** 4404 * @hide 4405 */ setDesintationFrame(SurfaceControl sc, int width, int height)4406 public Transaction setDesintationFrame(SurfaceControl sc, int width, int height) { 4407 checkPreconditions(sc); 4408 nativeSetDestinationFrame(mNativeObject, sc.mNativeObject, 0, 0, width, height); 4409 return this; 4410 } 4411 4412 /** 4413 * Merge the other transaction into this transaction, clearing the 4414 * other transaction as if it had been applied. 4415 * 4416 * @param other The transaction to merge in to this one. 4417 * @return This transaction. 4418 */ 4419 @NonNull merge(@onNull Transaction other)4420 public Transaction merge(@NonNull Transaction other) { 4421 if (this == other) { 4422 return this; 4423 } 4424 mResizedSurfaces.putAll(other.mResizedSurfaces); 4425 other.mResizedSurfaces.clear(); 4426 mReparentedSurfaces.putAll(other.mReparentedSurfaces); 4427 other.mReparentedSurfaces.clear(); 4428 nativeMergeTransaction(mNativeObject, other.mNativeObject); 4429 return this; 4430 } 4431 4432 /** 4433 * Equivalent to reparent with a null parent, in that it removes 4434 * the SurfaceControl from the scene, but it also releases 4435 * the local resources (by calling {@link SurfaceControl#release}) 4436 * after this method returns, {@link SurfaceControl#isValid} will return 4437 * false for the argument. 4438 * 4439 * @param sc The surface to remove and release. 4440 * @return This transaction 4441 * @hide 4442 */ 4443 @NonNull remove(@onNull SurfaceControl sc)4444 public Transaction remove(@NonNull SurfaceControl sc) { 4445 reparent(sc, null); 4446 sc.release(); 4447 return this; 4448 } 4449 4450 /** 4451 * Sets the frame timeline to use in SurfaceFlinger. 4452 * 4453 * A frame timeline should be chosen based on the frame deadline the application 4454 * can meet when rendering the frame and the application's desired presentation time. 4455 * By setting a frame timeline, SurfaceFlinger tries to present the frame at the 4456 * corresponding expected presentation time. 4457 * 4458 * To receive frame timelines, a callback must be posted to Choreographer using 4459 * {@link Choreographer#postVsyncCallback} The vsyncId can then be extracted from the 4460 * {@link Choreographer.FrameTimeline#getVsyncId}. 4461 * 4462 * @param vsyncId The vsync ID received from Choreographer, setting the frame's 4463 * presentation target to the corresponding expected presentation time 4464 * and deadline from the frame to be rendered. A stale or invalid value 4465 * will be ignored. 4466 * 4467 */ 4468 @FlaggedApi(Flags.FLAG_SDK_DESIRED_PRESENT_TIME) 4469 @NonNull setFrameTimeline(long vsyncId)4470 public Transaction setFrameTimeline(long vsyncId) { 4471 if (!Flags.sdkDesiredPresentTime()) { 4472 Log.w(TAG, "addTransactionCompletedListener was called but flag is disabled"); 4473 return this; 4474 } 4475 nativeSetFrameTimelineVsync(mNativeObject, vsyncId); 4476 return this; 4477 } 4478 4479 /** @hide */ 4480 @NonNull setFrameTimelineVsync(long frameTimelineVsyncId)4481 public Transaction setFrameTimelineVsync(long frameTimelineVsyncId) { 4482 nativeSetFrameTimelineVsync(mNativeObject, frameTimelineVsyncId); 4483 return this; 4484 } 4485 4486 /** 4487 * Request to add a {@link TransactionCommittedListener}. 4488 * 4489 * The callback is invoked when transaction is applied and the updates are ready to be 4490 * presented. This callback does not mean buffers have been released! It simply means that 4491 * any new transactions applied will not overwrite the transaction for which we are 4492 * receiving a callback and instead will be included in the next frame. If you are trying 4493 * to avoid dropping frames (overwriting transactions), and unable to use timestamps (Which 4494 * provide a more efficient solution), then this method provides a method to pace your 4495 * transaction application. 4496 * The listener is invoked once the transaction is applied, and never again. Multiple 4497 * listeners can be added to the same transaction, however the order the listeners will 4498 * be called is not guaranteed. 4499 * 4500 * @param executor The executor that the callback should be invoked on. 4501 * @param listener The callback that will be invoked when the transaction has been 4502 * committed. 4503 */ 4504 @NonNull addTransactionCommittedListener( @onNull @allbackExecutor Executor executor, @NonNull TransactionCommittedListener listener)4505 public Transaction addTransactionCommittedListener( 4506 @NonNull @CallbackExecutor Executor executor, 4507 @NonNull TransactionCommittedListener listener) { 4508 TransactionCommittedListener listenerInner = 4509 () -> executor.execute(listener::onTransactionCommitted); 4510 nativeAddTransactionCommittedListener(mNativeObject, listenerInner); 4511 return this; 4512 } 4513 4514 /** 4515 * Request to add a TransactionCompletedListener. 4516 * 4517 * The listener is invoked when transaction is presented, and never again. Multiple 4518 * listeners can be added to the same transaction, however the order the listeners will 4519 * be called is not guaranteed. 4520 * 4521 * @param executor The executor that the callback should be invoked on. 4522 * @param listener The callback that will be invoked when the transaction has been 4523 * completed. 4524 */ 4525 @FlaggedApi(Flags.FLAG_SDK_DESIRED_PRESENT_TIME) 4526 @NonNull addTransactionCompletedListener( @onNull @allbackExecutor Executor executor, @NonNull Consumer<TransactionStats> listener)4527 public Transaction addTransactionCompletedListener( 4528 @NonNull @CallbackExecutor Executor executor, 4529 @NonNull Consumer<TransactionStats> listener) { 4530 4531 if (!Flags.sdkDesiredPresentTime()) { 4532 Log.w(TAG, "addTransactionCompletedListener was called but flag is disabled"); 4533 return this; 4534 } 4535 Consumer<TransactionStats> listenerInner = stats -> executor.execute( 4536 () -> listener.andThen(TransactionStats::close).accept(stats)); 4537 nativeAddTransactionCompletedListener(mNativeObject, listenerInner); 4538 return this; 4539 } 4540 4541 /** 4542 * Sets a callback to receive feedback about the presentation of a {@link SurfaceControl}. 4543 * When the {@link SurfaceControl} is presented according to the passed in 4544 * {@link TrustedPresentationThresholds}, it is said to "enter the state", and receives the 4545 * callback with {@code true}. When the conditions fall out of thresholds, it is then 4546 * said to leave the state. 4547 * <p> 4548 * There are a few simple thresholds: 4549 * <ul> 4550 * <li>minAlpha: Lower bound on computed alpha</li> 4551 * <li>minFractionRendered: Lower bounds on fraction of pixels that were rendered</li> 4552 * <li>stabilityThresholdMs: A time that alpha and fraction rendered must remain within 4553 * bounds before we can "enter the state" </li> 4554 * </ul> 4555 * <p> 4556 * The fraction of pixels rendered is a computation based on scale, crop 4557 * and occlusion. The calculation may be somewhat counterintuitive, so we 4558 * can work through an example. Imagine we have a SurfaceControl with a 100x100 buffer 4559 * which is occluded by (10x100) pixels on the left, and cropped by (100x10) pixels 4560 * on the top. Furthermore imagine this SurfaceControl is scaled by 0.9 in both dimensions. 4561 * (c=crop,o=occluded,b=both,x=none) 4562 * 4563 * <blockquote> 4564 * <table> 4565 * <caption></caption> 4566 * <tr><td>b</td><td>c</td><td>c</td><td>c</td></tr> 4567 * <tr><td>o</td><td>x</td><td>x</td><td>x</td></tr> 4568 * <tr><td>o</td><td>x</td><td>x</td><td>x</td></tr> 4569 * <tr><td>o</td><td>x</td><td>x</td><td>x</td></tr> 4570 * </table> 4571 * </blockquote> 4572 * <p> 4573 * We first start by computing fr=xscale*yscale=0.9*0.9=0.81, indicating 4574 * that "81%" of the pixels were rendered. This corresponds to what was 100 4575 * pixels being displayed in 81 pixels. This is somewhat of an abuse of 4576 * language, as the information of merged pixels isn't totally lost, but 4577 * we err on the conservative side. 4578 * <p> 4579 * We then repeat a similar process for the crop and covered regions and 4580 * accumulate the results: fr = fr * (fractionNotCropped) * (fractionNotCovered) 4581 * So for this example we would get 0.9*0.9*0.9*0.9=0.65... 4582 * <p> 4583 * Notice that this is not completely accurate, as we have double counted 4584 * the region marked as b. However we only wanted a "lower bound" and so it 4585 * is ok to err in this direction. Selection of the threshold will ultimately 4586 * be somewhat arbitrary, and so there are some somewhat arbitrary decisions in 4587 * this API as well. 4588 * <p> 4589 * 4590 * @param sc The {@link SurfaceControl} to set the callback on 4591 * @param thresholds The {@link TrustedPresentationThresholds} that will specify when the to 4592 * invoke the callback. 4593 * @param executor The {@link Executor} where the callback will be invoked on. 4594 * @param listener The {@link Consumer} that will receive the callbacks when entered or 4595 * exited the threshold. 4596 * @return This transaction 4597 * @see TrustedPresentationThresholds 4598 * @deprecated Use 4599 * {@link WindowManager#registerTrustedPresentationListener(IBinder, 4600 * android.window.TrustedPresentationThresholds, Executor, Consumer)} instead. 4601 */ 4602 @Deprecated 4603 @NonNull setTrustedPresentationCallback(@onNull SurfaceControl sc, @NonNull TrustedPresentationThresholds thresholds, @NonNull Executor executor, @NonNull Consumer<Boolean> listener)4604 public Transaction setTrustedPresentationCallback(@NonNull SurfaceControl sc, 4605 @NonNull TrustedPresentationThresholds thresholds, @NonNull Executor executor, 4606 @NonNull Consumer<Boolean> listener) { 4607 checkPreconditions(sc); 4608 TrustedPresentationCallback tpc = new TrustedPresentationCallback() { 4609 @Override 4610 public void onTrustedPresentationChanged(boolean inTrustedPresentationState) { 4611 executor.execute( 4612 () -> listener.accept(inTrustedPresentationState)); 4613 } 4614 }; 4615 4616 if (sc.mTrustedPresentationCallback != null) { 4617 sc.mTrustedPresentationCallback.mFreeNativeResources.run(); 4618 } 4619 4620 nativeSetTrustedPresentationCallback(mNativeObject, sc.mNativeObject, 4621 tpc.mNativeObject, thresholds); 4622 sc.mTrustedPresentationCallback = tpc; 4623 return this; 4624 } 4625 4626 /** 4627 * Clears the callback for a specific {@link SurfaceControl} 4628 * 4629 * @param sc The SurfaceControl that the callback should be cleared from 4630 * @return This transaction 4631 * @deprecated Use {@link WindowManager#unregisterTrustedPresentationListener(Consumer)} 4632 * instead. 4633 */ 4634 @Deprecated 4635 @NonNull clearTrustedPresentationCallback(@onNull SurfaceControl sc)4636 public Transaction clearTrustedPresentationCallback(@NonNull SurfaceControl sc) { 4637 checkPreconditions(sc); 4638 nativeClearTrustedPresentationCallback(mNativeObject, sc.mNativeObject); 4639 if (sc.mTrustedPresentationCallback != null) { 4640 sc.mTrustedPresentationCallback.mFreeNativeResources.run(); 4641 sc.mTrustedPresentationCallback = null; 4642 } 4643 return this; 4644 } 4645 4646 /** 4647 * Specifies a desiredPresentTimeNanos for the transaction. The framework will try to 4648 * present the transaction at or after the time specified. 4649 * 4650 * Transactions will not be presented until all of their acquire fences have signaled even 4651 * if the app requests an earlier present time. 4652 * 4653 * If an earlier transaction has a desired present time of x, and a later transaction has 4654 * a desired present time that is before x, the later transaction will not preempt the 4655 * earlier transaction. 4656 * 4657 * @param desiredPresentTimeNanos The desired time (in CLOCK_MONOTONIC) for the transaction. 4658 * @return This transaction 4659 */ 4660 @FlaggedApi(Flags.FLAG_SDK_DESIRED_PRESENT_TIME) 4661 @NonNull setDesiredPresentTimeNanos(long desiredPresentTimeNanos)4662 public Transaction setDesiredPresentTimeNanos(long desiredPresentTimeNanos) { 4663 if (!Flags.sdkDesiredPresentTime()) { 4664 Log.w(TAG, "addTransactionCompletedListener was called but flag is disabled"); 4665 return this; 4666 } 4667 nativeSetDesiredPresentTimeNanos(mNativeObject, desiredPresentTimeNanos); 4668 return this; 4669 } 4670 /** 4671 * Writes the transaction to parcel, clearing the transaction as if it had been applied so 4672 * it can be used to store future transactions. It's the responsibility of the parcel 4673 * reader to apply the original transaction. 4674 * 4675 * @param dest parcel to write the transaction to 4676 * @param flags 4677 */ 4678 @Override writeToParcel(@onNull Parcel dest, @WriteFlags int flags)4679 public void writeToParcel(@NonNull Parcel dest, @WriteFlags int flags) { 4680 if (mNativeObject == 0) { 4681 dest.writeInt(0); 4682 return; 4683 } 4684 4685 dest.writeInt(1); 4686 nativeWriteTransactionToParcel(mNativeObject, dest); 4687 if ((flags & Parcelable.PARCELABLE_WRITE_RETURN_VALUE) != 0) { 4688 nativeClearTransaction(mNativeObject); 4689 } 4690 } 4691 readFromParcel(Parcel in)4692 private void readFromParcel(Parcel in) { 4693 mNativeObject = 0; 4694 if (in.readInt() != 0) { 4695 mNativeObject = nativeReadTransactionFromParcel(in); 4696 mFreeNativeResources = sRegistry.registerNativeAllocation(this, mNativeObject); 4697 } 4698 } 4699 4700 @Override describeContents()4701 public int describeContents() { 4702 return 0; 4703 } 4704 4705 public static final @NonNull Creator<Transaction> CREATOR = new Creator<Transaction>() { 4706 @Override 4707 public Transaction createFromParcel(Parcel in) { 4708 return new Transaction(in); 4709 } 4710 @Override 4711 public Transaction[] newArray(int size) { 4712 return new Transaction[size]; 4713 } 4714 }; 4715 } 4716 4717 /** 4718 * A debugging utility subclass of SurfaceControl.Transaction. At construction 4719 * you can pass in a monitor object, and all the other methods will throw an exception 4720 * if the monitor is not held when they are called. 4721 * @hide 4722 */ 4723 public static class LockDebuggingTransaction extends SurfaceControl.Transaction { 4724 Object mMonitor; 4725 LockDebuggingTransaction(Object o)4726 public LockDebuggingTransaction(Object o) { 4727 mMonitor = o; 4728 } 4729 4730 @Override checkPreconditions(SurfaceControl sc)4731 protected void checkPreconditions(SurfaceControl sc) { 4732 super.checkPreconditions(sc); 4733 if (!Thread.holdsLock(mMonitor)) { 4734 throw new RuntimeException( 4735 "Unlocked access to synchronized SurfaceControl.Transaction"); 4736 } 4737 } 4738 } 4739 4740 /** 4741 * @hide 4742 */ resize(int w, int h)4743 public void resize(int w, int h) { 4744 mWidth = w; 4745 mHeight = h; 4746 nativeUpdateDefaultBufferSize(mNativeObject, w, h); 4747 } 4748 4749 /** 4750 * @hide 4751 */ getTransformHint()4752 public @SurfaceControl.BufferTransform int getTransformHint() { 4753 checkNotReleased(); 4754 return nativeGetTransformHint(mNativeObject); 4755 } 4756 4757 /** 4758 * Update the transform hint of current SurfaceControl. Only affect if type is 4759 * {@link #FX_SURFACE_BLAST} 4760 * 4761 * The transform hint is used to prevent allocating a buffer of different size when a 4762 * layer is rotated. The producer can choose to consume the hint and allocate the buffer 4763 * with the same size. 4764 * @hide 4765 */ setTransformHint(@urfaceControl.BufferTransform int transformHint)4766 public void setTransformHint(@SurfaceControl.BufferTransform int transformHint) { 4767 nativeSetTransformHint(mNativeObject, transformHint); 4768 } 4769 4770 /** 4771 * @hide 4772 */ getLayerId()4773 public int getLayerId() { 4774 if (mNativeObject != 0) { 4775 return nativeGetLayerId(mNativeObject); 4776 } 4777 4778 return -1; 4779 } 4780 4781 // Called by native invokeReleaseCallback(Consumer<SyncFence> callback, long nativeFencePtr)4782 private static void invokeReleaseCallback(Consumer<SyncFence> callback, long nativeFencePtr) { 4783 SyncFence fence = new SyncFence(nativeFencePtr); 4784 callback.accept(fence); 4785 } 4786 4787 /** 4788 * @hide 4789 */ getStalledTransactionInfo(int pid)4790 public static StalledTransactionInfo getStalledTransactionInfo(int pid) { 4791 return nativeGetStalledTransactionInfo(pid); 4792 } 4793 4794 /** 4795 * Notify the SurfaceFlinger to capture transaction traces when shutdown. 4796 * @hide 4797 */ notifyShutdown()4798 public static void notifyShutdown() { 4799 nativeNotifyShutdown(); 4800 } 4801 } 4802