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.NAME; 27 28 import android.annotation.FloatRange; 29 import android.annotation.IntDef; 30 import android.annotation.IntRange; 31 import android.annotation.NonNull; 32 import android.annotation.Nullable; 33 import android.annotation.Size; 34 import android.annotation.TestApi; 35 import android.compat.annotation.UnsupportedAppUsage; 36 import android.graphics.Bitmap; 37 import android.graphics.ColorSpace; 38 import android.graphics.GraphicBuffer; 39 import android.graphics.Matrix; 40 import android.graphics.PixelFormat; 41 import android.graphics.Point; 42 import android.graphics.Rect; 43 import android.graphics.Region; 44 import android.hardware.HardwareBuffer; 45 import android.hardware.display.DeviceProductInfo; 46 import android.hardware.display.DisplayedContentSample; 47 import android.hardware.display.DisplayedContentSamplingAttributes; 48 import android.os.Build; 49 import android.os.IBinder; 50 import android.os.Parcel; 51 import android.os.Parcelable; 52 import android.util.ArrayMap; 53 import android.util.Log; 54 import android.util.SparseIntArray; 55 import android.util.proto.ProtoOutputStream; 56 import android.view.Surface.OutOfResourcesException; 57 58 import com.android.internal.annotations.GuardedBy; 59 import com.android.internal.util.VirtualRefBasePtr; 60 61 import dalvik.system.CloseGuard; 62 63 import libcore.util.NativeAllocationRegistry; 64 65 import java.io.Closeable; 66 import java.lang.annotation.Retention; 67 import java.lang.annotation.RetentionPolicy; 68 import java.lang.ref.WeakReference; 69 import java.nio.ByteBuffer; 70 import java.nio.ByteOrder; 71 import java.util.ArrayList; 72 import java.util.Arrays; 73 import java.util.Objects; 74 import java.util.concurrent.CountDownLatch; 75 import java.util.concurrent.TimeUnit; 76 77 /** 78 * Handle to an on-screen Surface managed by the system compositor. The SurfaceControl is 79 * a combination of a buffer source, and metadata about how to display the buffers. 80 * By constructing a {@link Surface} from this SurfaceControl you can submit buffers to be 81 * composited. Using {@link SurfaceControl.Transaction} you can manipulate various 82 * properties of how the buffer will be displayed on-screen. SurfaceControl's are 83 * arranged into a scene-graph like hierarchy, and as such any SurfaceControl may have 84 * a parent. Geometric properties like transform, crop, and Z-ordering will be inherited 85 * from the parent, as if the child were content in the parents buffer stream. 86 */ 87 public final class SurfaceControl implements Parcelable { 88 private static final String TAG = "SurfaceControl"; 89 nativeCreate(SurfaceSession session, String name, int w, int h, int format, int flags, long parentObject, Parcel metadata)90 private static native long nativeCreate(SurfaceSession session, String name, 91 int w, int h, int format, int flags, long parentObject, Parcel metadata) 92 throws OutOfResourcesException; nativeReadFromParcel(Parcel in)93 private static native long nativeReadFromParcel(Parcel in); nativeCopyFromSurfaceControl(long nativeObject)94 private static native long nativeCopyFromSurfaceControl(long nativeObject); nativeWriteToParcel(long nativeObject, Parcel out)95 private static native void nativeWriteToParcel(long nativeObject, Parcel out); nativeRelease(long nativeObject)96 private static native void nativeRelease(long nativeObject); nativeDisconnect(long nativeObject)97 private static native void nativeDisconnect(long nativeObject); nativeUpdateDefaultBufferSize(long nativeObject, int width, int height)98 private static native void nativeUpdateDefaultBufferSize(long nativeObject, int width, int height); nativeCaptureDisplay(DisplayCaptureArgs captureArgs, ScreenCaptureListener captureListener)99 private static native int nativeCaptureDisplay(DisplayCaptureArgs captureArgs, 100 ScreenCaptureListener captureListener); nativeCaptureLayers(LayerCaptureArgs captureArgs, ScreenCaptureListener captureListener)101 private static native int nativeCaptureLayers(LayerCaptureArgs captureArgs, 102 ScreenCaptureListener captureListener); nativeMirrorSurface(long mirrorOfObject)103 private static native long nativeMirrorSurface(long mirrorOfObject); nativeCreateTransaction()104 private static native long nativeCreateTransaction(); nativeGetNativeTransactionFinalizer()105 private static native long nativeGetNativeTransactionFinalizer(); nativeApplyTransaction(long transactionObj, boolean sync)106 private static native void nativeApplyTransaction(long transactionObj, boolean sync); nativeMergeTransaction(long transactionObj, long otherTransactionObj)107 private static native void nativeMergeTransaction(long transactionObj, 108 long otherTransactionObj); nativeClearTransaction(long transactionObj)109 private static native void nativeClearTransaction(long transactionObj); nativeSetAnimationTransaction(long transactionObj)110 private static native void nativeSetAnimationTransaction(long transactionObj); nativeSetEarlyWakeupStart(long transactionObj)111 private static native void nativeSetEarlyWakeupStart(long transactionObj); nativeSetEarlyWakeupEnd(long transactionObj)112 private static native void nativeSetEarlyWakeupEnd(long transactionObj); 113 nativeSetLayer(long transactionObj, long nativeObject, int zorder)114 private static native void nativeSetLayer(long transactionObj, long nativeObject, int zorder); nativeSetRelativeLayer(long transactionObj, long nativeObject, long relativeToObject, int zorder)115 private static native void nativeSetRelativeLayer(long transactionObj, long nativeObject, 116 long relativeToObject, int zorder); nativeSetPosition(long transactionObj, long nativeObject, float x, float y)117 private static native void nativeSetPosition(long transactionObj, long nativeObject, 118 float x, float y); nativeSetSize(long transactionObj, long nativeObject, int w, int h)119 private static native void nativeSetSize(long transactionObj, long nativeObject, int w, int h); nativeSetTransparentRegionHint(long transactionObj, long nativeObject, Region region)120 private static native void nativeSetTransparentRegionHint(long transactionObj, 121 long nativeObject, Region region); nativeSetAlpha(long transactionObj, long nativeObject, float alpha)122 private static native void nativeSetAlpha(long transactionObj, long nativeObject, float alpha); nativeSetMatrix(long transactionObj, long nativeObject, float dsdx, float dtdx, float dtdy, float dsdy)123 private static native void nativeSetMatrix(long transactionObj, long nativeObject, 124 float dsdx, float dtdx, 125 float dtdy, float dsdy); nativeSetColorTransform(long transactionObj, long nativeObject, float[] matrix, float[] translation)126 private static native void nativeSetColorTransform(long transactionObj, long nativeObject, 127 float[] matrix, float[] translation); nativeSetColorSpaceAgnostic(long transactionObj, long nativeObject, boolean agnostic)128 private static native void nativeSetColorSpaceAgnostic(long transactionObj, long nativeObject, 129 boolean agnostic); nativeSetGeometry(long transactionObj, long nativeObject, Rect sourceCrop, Rect dest, long orientation)130 private static native void nativeSetGeometry(long transactionObj, long nativeObject, 131 Rect sourceCrop, Rect dest, long orientation); nativeSetColor(long transactionObj, long nativeObject, float[] color)132 private static native void nativeSetColor(long transactionObj, long nativeObject, float[] color); nativeSetFlags(long transactionObj, long nativeObject, int flags, int mask)133 private static native void nativeSetFlags(long transactionObj, long nativeObject, 134 int flags, int mask); nativeSetFrameRateSelectionPriority(long transactionObj, long nativeObject, int priority)135 private static native void nativeSetFrameRateSelectionPriority(long transactionObj, 136 long nativeObject, int priority); nativeSetWindowCrop(long transactionObj, long nativeObject, int l, int t, int r, int b)137 private static native void nativeSetWindowCrop(long transactionObj, long nativeObject, 138 int l, int t, int r, int b); nativeSetCornerRadius(long transactionObj, long nativeObject, float cornerRadius)139 private static native void nativeSetCornerRadius(long transactionObj, long nativeObject, 140 float cornerRadius); nativeSetBackgroundBlurRadius(long transactionObj, long nativeObject, int blurRadius)141 private static native void nativeSetBackgroundBlurRadius(long transactionObj, long nativeObject, 142 int blurRadius); nativeSetLayerStack(long transactionObj, long nativeObject, int layerStack)143 private static native void nativeSetLayerStack(long transactionObj, long nativeObject, 144 int layerStack); nativeSetBlurRegions(long transactionObj, long nativeObj, float[][] regions, int length)145 private static native void nativeSetBlurRegions(long transactionObj, long nativeObj, 146 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)147 private static native void nativeSetStretchEffect(long transactionObj, long nativeObj, 148 float width, float height, float vecX, float vecY, 149 float maxStretchAmountX, float maxStretchAmountY, float childRelativeLeft, 150 float childRelativeTop, float childRelativeRight, float childRelativeBottom); nativeSetTrustedOverlay(long transactionObj, long nativeObject, boolean isTrustedOverlay)151 private static native void nativeSetTrustedOverlay(long transactionObj, long nativeObject, 152 boolean isTrustedOverlay); 153 nativeClearContentFrameStats(long nativeObject)154 private static native boolean nativeClearContentFrameStats(long nativeObject); nativeGetContentFrameStats(long nativeObject, WindowContentFrameStats outStats)155 private static native boolean nativeGetContentFrameStats(long nativeObject, WindowContentFrameStats outStats); nativeClearAnimationFrameStats()156 private static native boolean nativeClearAnimationFrameStats(); nativeGetAnimationFrameStats(WindowAnimationFrameStats outStats)157 private static native boolean nativeGetAnimationFrameStats(WindowAnimationFrameStats outStats); 158 nativeGetPhysicalDisplayIds()159 private static native long[] nativeGetPhysicalDisplayIds(); nativeGetPhysicalDisplayToken(long physicalDisplayId)160 private static native IBinder nativeGetPhysicalDisplayToken(long physicalDisplayId); nativeCreateDisplay(String name, boolean secure)161 private static native IBinder nativeCreateDisplay(String name, boolean secure); nativeDestroyDisplay(IBinder displayToken)162 private static native void nativeDestroyDisplay(IBinder displayToken); nativeSetDisplaySurface(long transactionObj, IBinder displayToken, long nativeSurfaceObject)163 private static native void nativeSetDisplaySurface(long transactionObj, 164 IBinder displayToken, long nativeSurfaceObject); nativeSetDisplayLayerStack(long transactionObj, IBinder displayToken, int layerStack)165 private static native void nativeSetDisplayLayerStack(long transactionObj, 166 IBinder displayToken, int layerStack); nativeSetDisplayProjection(long transactionObj, IBinder displayToken, int orientation, int l, int t, int r, int b, int L, int T, int R, int B)167 private static native void nativeSetDisplayProjection(long transactionObj, 168 IBinder displayToken, int orientation, 169 int l, int t, int r, int b, 170 int L, int T, int R, int B); nativeSetDisplaySize(long transactionObj, IBinder displayToken, int width, int height)171 private static native void nativeSetDisplaySize(long transactionObj, IBinder displayToken, 172 int width, int height); nativeGetStaticDisplayInfo(IBinder displayToken)173 private static native StaticDisplayInfo nativeGetStaticDisplayInfo(IBinder displayToken); nativeGetDynamicDisplayInfo(IBinder displayToken)174 private static native DynamicDisplayInfo nativeGetDynamicDisplayInfo(IBinder displayToken); 175 private static native DisplayedContentSamplingAttributes nativeGetDisplayedContentSamplingAttributes(IBinder displayToken)176 nativeGetDisplayedContentSamplingAttributes(IBinder displayToken); nativeSetDisplayedContentSamplingEnabled(IBinder displayToken, boolean enable, int componentMask, int maxFrames)177 private static native boolean nativeSetDisplayedContentSamplingEnabled(IBinder displayToken, 178 boolean enable, int componentMask, int maxFrames); nativeGetDisplayedContentSample( IBinder displayToken, long numFrames, long timestamp)179 private static native DisplayedContentSample nativeGetDisplayedContentSample( 180 IBinder displayToken, long numFrames, long timestamp); nativeSetDesiredDisplayModeSpecs(IBinder displayToken, DesiredDisplayModeSpecs desiredDisplayModeSpecs)181 private static native boolean nativeSetDesiredDisplayModeSpecs(IBinder displayToken, 182 DesiredDisplayModeSpecs desiredDisplayModeSpecs); 183 private static native DesiredDisplayModeSpecs nativeGetDesiredDisplayModeSpecs(IBinder displayToken)184 nativeGetDesiredDisplayModeSpecs(IBinder displayToken); nativeGetDisplayNativePrimaries( IBinder displayToken)185 private static native DisplayPrimaries nativeGetDisplayNativePrimaries( 186 IBinder displayToken); nativeGetCompositionDataspaces()187 private static native int[] nativeGetCompositionDataspaces(); nativeSetActiveColorMode(IBinder displayToken, int colorMode)188 private static native boolean nativeSetActiveColorMode(IBinder displayToken, 189 int colorMode); nativeSetAutoLowLatencyMode(IBinder displayToken, boolean on)190 private static native void nativeSetAutoLowLatencyMode(IBinder displayToken, boolean on); nativeSetGameContentType(IBinder displayToken, boolean on)191 private static native void nativeSetGameContentType(IBinder displayToken, boolean on); nativeSetDisplayPowerMode( IBinder displayToken, int mode)192 private static native void nativeSetDisplayPowerMode( 193 IBinder displayToken, int mode); nativeReparent(long transactionObj, long nativeObject, long newParentNativeObject)194 private static native void nativeReparent(long transactionObj, long nativeObject, 195 long newParentNativeObject); nativeSetBuffer(long transactionObj, long nativeObject, GraphicBuffer buffer)196 private static native void nativeSetBuffer(long transactionObj, long nativeObject, 197 GraphicBuffer buffer); nativeSetColorSpace(long transactionObj, long nativeObject, int colorSpace)198 private static native void nativeSetColorSpace(long transactionObj, long nativeObject, 199 int colorSpace); 200 nativeOverrideHdrTypes(IBinder displayToken, int[] modes)201 private static native void nativeOverrideHdrTypes(IBinder displayToken, int[] modes); 202 nativeSetInputWindowInfo(long transactionObj, long nativeObject, InputWindowHandle handle)203 private static native void nativeSetInputWindowInfo(long transactionObj, long nativeObject, 204 InputWindowHandle handle); 205 nativeGetProtectedContentSupport()206 private static native boolean nativeGetProtectedContentSupport(); nativeSetMetadata(long transactionObj, long nativeObject, int key, Parcel data)207 private static native void nativeSetMetadata(long transactionObj, long nativeObject, int key, 208 Parcel data); nativeSyncInputWindows(long transactionObj)209 private static native void nativeSyncInputWindows(long transactionObj); nativeGetDisplayBrightnessSupport(IBinder displayToken)210 private static native boolean nativeGetDisplayBrightnessSupport(IBinder displayToken); nativeSetDisplayBrightness(IBinder displayToken, float sdrBrightness, float sdrBrightnessNits, float displayBrightness, float displayBrightnessNits)211 private static native boolean nativeSetDisplayBrightness(IBinder displayToken, 212 float sdrBrightness, float sdrBrightnessNits, float displayBrightness, 213 float displayBrightnessNits); nativeReadTransactionFromParcel(Parcel in)214 private static native long nativeReadTransactionFromParcel(Parcel in); nativeWriteTransactionToParcel(long nativeObject, Parcel out)215 private static native void nativeWriteTransactionToParcel(long nativeObject, Parcel out); nativeSetShadowRadius(long transactionObj, long nativeObject, float shadowRadius)216 private static native void nativeSetShadowRadius(long transactionObj, long nativeObject, 217 float shadowRadius); nativeSetGlobalShadowSettings(@ize4) float[] ambientColor, @Size(4) float[] spotColor, float lightPosY, float lightPosZ, float lightRadius)218 private static native void nativeSetGlobalShadowSettings(@Size(4) float[] ambientColor, 219 @Size(4) float[] spotColor, float lightPosY, float lightPosZ, float lightRadius); 220 nativeSetFrameRate(long transactionObj, long nativeObject, float frameRate, int compatibility, int changeFrameRateStrategy)221 private static native void nativeSetFrameRate(long transactionObj, long nativeObject, 222 float frameRate, int compatibility, int changeFrameRateStrategy); nativeGetHandle(long nativeObject)223 private static native long nativeGetHandle(long nativeObject); 224 nativeAcquireFrameRateFlexibilityToken()225 private static native long nativeAcquireFrameRateFlexibilityToken(); nativeReleaseFrameRateFlexibilityToken(long token)226 private static native void nativeReleaseFrameRateFlexibilityToken(long token); nativeSetFixedTransformHint(long transactionObj, long nativeObject, int transformHint)227 private static native void nativeSetFixedTransformHint(long transactionObj, long nativeObject, 228 int transformHint); nativeSetFocusedWindow(long transactionObj, IBinder toToken, String windowName, IBinder focusedToken, String focusedWindowName, int displayId)229 private static native void nativeSetFocusedWindow(long transactionObj, IBinder toToken, 230 String windowName, IBinder focusedToken, String focusedWindowName, int displayId); nativeSetFrameTimelineVsync(long transactionObj, long frameTimelineVsyncId)231 private static native void nativeSetFrameTimelineVsync(long transactionObj, 232 long frameTimelineVsyncId); nativeAddJankDataListener(long nativeListener, long nativeSurfaceControl)233 private static native void nativeAddJankDataListener(long nativeListener, 234 long nativeSurfaceControl); nativeRemoveJankDataListener(long nativeListener)235 private static native void nativeRemoveJankDataListener(long nativeListener); nativeCreateJankDataListenerWrapper(OnJankDataListener listener)236 private static native long nativeCreateJankDataListenerWrapper(OnJankDataListener listener); nativeGetGPUContextPriority()237 private static native int nativeGetGPUContextPriority(); nativeSetTransformHint(long nativeObject, int transformHint)238 private static native void nativeSetTransformHint(long nativeObject, int transformHint); nativeGetTransformHint(long nativeObject)239 private static native int nativeGetTransformHint(long nativeObject); 240 241 @Nullable 242 @GuardedBy("mLock") 243 private ArrayList<OnReparentListener> mReparentListeners; 244 245 /** 246 * Listener to observe surface reparenting. 247 * 248 * @hide 249 */ 250 public interface OnReparentListener { 251 252 /** 253 * Callback for reparenting surfaces. 254 * 255 * Important: You should only interact with the provided surface control 256 * only if you have a contract with its owner to avoid them closing it 257 * under you or vise versa. 258 * 259 * @param transaction The transaction that would commit reparenting. 260 * @param parent The future parent surface. 261 */ onReparent(@onNull Transaction transaction, @Nullable SurfaceControl parent)262 void onReparent(@NonNull Transaction transaction, @Nullable SurfaceControl parent); 263 } 264 265 /** 266 * Jank information to be fed back via {@link OnJankDataListener}. 267 * @hide 268 */ 269 public static class JankData { 270 271 /** @hide */ 272 @IntDef(flag = true, value = {JANK_NONE, 273 DISPLAY_HAL, 274 JANK_SURFACEFLINGER_DEADLINE_MISSED, 275 JANK_SURFACEFLINGER_GPU_DEADLINE_MISSED, 276 JANK_APP_DEADLINE_MISSED, 277 PREDICTION_ERROR, 278 SURFACE_FLINGER_SCHEDULING}) 279 @Retention(RetentionPolicy.SOURCE) 280 public @interface JankType {} 281 282 // Needs to be kept in sync with frameworks/native/libs/gui/include/gui/JankInfo.h 283 284 // No Jank 285 public static final int JANK_NONE = 0x0; 286 287 // Jank not related to SurfaceFlinger or the App 288 public static final int DISPLAY_HAL = 0x1; 289 // SF took too long on the CPU 290 public static final int JANK_SURFACEFLINGER_DEADLINE_MISSED = 0x2; 291 // SF took too long on the GPU 292 public static final int JANK_SURFACEFLINGER_GPU_DEADLINE_MISSED = 0x4; 293 // Either App or GPU took too long on the frame 294 public static final int JANK_APP_DEADLINE_MISSED = 0x8; 295 // Predictions live for 120ms, if prediction is expired for a frame, there is definitely a 296 // jank 297 // associated with the App if this is for a SurfaceFrame, and SF for a DisplayFrame. 298 public static final int PREDICTION_ERROR = 0x10; 299 // Latching a buffer early might cause an early present of the frame 300 public static final int SURFACE_FLINGER_SCHEDULING = 0x20; 301 // A buffer is said to be stuffed if it was expected to be presented on a vsync but was 302 // presented later because the previous buffer was presented in its expected vsync. This 303 // usually happens if there is an unexpectedly long frame causing the rest of the buffers 304 // to enter a stuffed state. 305 public static final int BUFFER_STUFFING = 0x40; 306 // Jank due to unknown reasons. 307 public static final int UNKNOWN = 0x80; 308 JankData(long frameVsyncId, @JankType int jankType)309 public JankData(long frameVsyncId, @JankType int jankType) { 310 this.frameVsyncId = frameVsyncId; 311 this.jankType = jankType; 312 } 313 314 public final long frameVsyncId; 315 public final @JankType int jankType; 316 } 317 318 /** 319 * Listener interface to be informed about SurfaceFlinger's jank classification for a specific 320 * surface. 321 * 322 * @see JankData 323 * @see #addJankDataListener 324 * @hide 325 */ 326 public static abstract class OnJankDataListener { 327 private final VirtualRefBasePtr mNativePtr; 328 OnJankDataListener()329 public OnJankDataListener() { 330 mNativePtr = new VirtualRefBasePtr(nativeCreateJankDataListenerWrapper(this)); 331 } 332 333 /** 334 * Called when new jank classifications are available. 335 */ onJankDataAvailable(JankData[] jankStats)336 public abstract void onJankDataAvailable(JankData[] jankStats); 337 } 338 339 private final CloseGuard mCloseGuard = CloseGuard.get(); 340 private String mName; 341 342 /** 343 * @hide 344 */ 345 public long mNativeObject; 346 private long mNativeHandle; 347 348 // TODO: Move width/height to native and fix locking through out. 349 private final Object mLock = new Object(); 350 @GuardedBy("mLock") 351 private int mWidth; 352 @GuardedBy("mLock") 353 private int mHeight; 354 355 private int mTransformHint; 356 357 private WeakReference<View> mLocalOwnerView; 358 359 static GlobalTransactionWrapper sGlobalTransaction; 360 static long sTransactionNestCount = 0; 361 362 /** 363 * Adds a reparenting listener. 364 * 365 * @param listener The listener. 366 * @return Whether listener was added. 367 * 368 * @hide 369 */ addOnReparentListener(@onNull OnReparentListener listener)370 public boolean addOnReparentListener(@NonNull OnReparentListener listener) { 371 synchronized (mLock) { 372 if (mReparentListeners == null) { 373 mReparentListeners = new ArrayList<>(1); 374 } 375 return mReparentListeners.add(listener); 376 } 377 } 378 379 /** 380 * Removes a reparenting listener. 381 * 382 * @param listener The listener. 383 * @return Whether listener was removed. 384 * 385 * @hide 386 */ removeOnReparentListener(@onNull OnReparentListener listener)387 public boolean removeOnReparentListener(@NonNull OnReparentListener listener) { 388 synchronized (mLock) { 389 final boolean removed = mReparentListeners.remove(listener); 390 if (mReparentListeners.isEmpty()) { 391 mReparentListeners = null; 392 } 393 return removed; 394 } 395 } 396 397 /* flags used in constructor (keep in sync with ISurfaceComposerClient.h) */ 398 399 /** 400 * Surface creation flag: Surface is created hidden 401 * @hide 402 */ 403 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) 404 public static final int HIDDEN = 0x00000004; 405 406 /** 407 * Surface creation flag: Skip this layer and its children when taking a screenshot. This 408 * also includes mirroring and screen recording, so the layers with flag SKIP_SCREENSHOT 409 * will not be included on non primary displays. 410 * @hide 411 */ 412 public static final int SKIP_SCREENSHOT = 0x00000040; 413 414 /** 415 * Surface creation flag: Special measures will be taken to disallow the surface's content to 416 * be copied. In particular, screenshots and secondary, non-secure displays will render black 417 * content instead of the surface content. 418 * 419 * @see #createDisplay(String, boolean) 420 * @hide 421 */ 422 public static final int SECURE = 0x00000080; 423 424 425 /** 426 * Queue up BufferStateLayer buffers instead of dropping the oldest buffer when this flag is 427 * set. This blocks the client until all the buffers have been presented. If the buffers 428 * have presentation timestamps, then we may drop buffers. 429 * @hide 430 */ 431 public static final int ENABLE_BACKPRESSURE = 0x00000100; 432 433 /** 434 * Surface creation flag: Creates a surface where color components are interpreted 435 * as "non pre-multiplied" by their alpha channel. Of course this flag is 436 * meaningless for surfaces without an alpha channel. By default 437 * surfaces are pre-multiplied, which means that each color component is 438 * already multiplied by its alpha value. In this case the blending 439 * equation used is: 440 * <p> 441 * <code>DEST = SRC + DEST * (1-SRC_ALPHA)</code> 442 * <p> 443 * By contrast, non pre-multiplied surfaces use the following equation: 444 * <p> 445 * <code>DEST = SRC * SRC_ALPHA * DEST * (1-SRC_ALPHA)</code> 446 * <p> 447 * pre-multiplied surfaces must always be used if transparent pixels are 448 * composited on top of each-other into the surface. A pre-multiplied 449 * surface can never lower the value of the alpha component of a given 450 * pixel. 451 * <p> 452 * In some rare situations, a non pre-multiplied surface is preferable. 453 * @hide 454 */ 455 public static final int NON_PREMULTIPLIED = 0x00000100; 456 457 /** 458 * Surface creation flag: Indicates that the surface must be considered opaque, 459 * even if its pixel format contains an alpha channel. This can be useful if an 460 * application needs full RGBA 8888 support for instance but will 461 * still draw every pixel opaque. 462 * <p> 463 * This flag is ignored if setAlpha() is used to make the surface non-opaque. 464 * Combined effects are (assuming a buffer format with an alpha channel): 465 * <ul> 466 * <li>OPAQUE + alpha(1.0) == opaque composition 467 * <li>OPAQUE + alpha(0.x) == blended composition 468 * <li>!OPAQUE + alpha(1.0) == blended composition 469 * <li>!OPAQUE + alpha(0.x) == blended composition 470 * </ul> 471 * If the underlying buffer lacks an alpha channel, the OPAQUE flag is effectively 472 * set automatically. 473 * @hide 474 */ 475 public static final int OPAQUE = 0x00000400; 476 477 /** 478 * Surface creation flag: Application requires a hardware-protected path to an 479 * external display sink. If a hardware-protected path is not available, 480 * then this surface will not be displayed on the external sink. 481 * 482 * @hide 483 */ 484 public static final int PROTECTED_APP = 0x00000800; 485 486 // 0x1000 is reserved for an independent DRM protected flag in framework 487 488 /** 489 * Surface creation flag: Window represents a cursor glyph. 490 * @hide 491 */ 492 public static final int CURSOR_WINDOW = 0x00002000; 493 494 /** 495 * Surface creation flag: Indicates the effect layer will not have a color fill on 496 * creation. 497 * 498 * @hide 499 */ 500 public static final int NO_COLOR_FILL = 0x00004000; 501 502 /** 503 * Surface creation flag: Creates a normal surface. 504 * This is the default. 505 * 506 * @hide 507 */ 508 public static final int FX_SURFACE_NORMAL = 0x00000000; 509 510 /** 511 * Surface creation flag: Creates a effect surface which 512 * represents a solid color and or shadows. 513 * 514 * @hide 515 */ 516 public static final int FX_SURFACE_EFFECT = 0x00020000; 517 518 /** 519 * Surface creation flag: Creates a container surface. 520 * This surface will have no buffers and will only be used 521 * as a container for other surfaces, or for its InputInfo. 522 * @hide 523 */ 524 public static final int FX_SURFACE_CONTAINER = 0x00080000; 525 526 /** 527 * @hide 528 */ 529 public static final int FX_SURFACE_BLAST = 0x00040000; 530 531 /** 532 * Mask used for FX values above. 533 * 534 * @hide 535 */ 536 public static final int FX_SURFACE_MASK = 0x000F0000; 537 538 /* flags used with setFlags() (keep in sync with ISurfaceComposer.h) */ 539 540 /** 541 * Surface flag: Hide the surface. 542 * Equivalent to calling hide(). 543 * Updates the value set during Surface creation (see {@link #HIDDEN}). 544 */ 545 private static final int SURFACE_HIDDEN = 0x01; 546 547 /** 548 * Surface flag: composite without blending when possible. 549 * Updates the value set during Surface creation (see {@link #OPAQUE}). 550 */ 551 private static final int SURFACE_OPAQUE = 0x02; 552 553 // Display power modes. 554 /** 555 * Display power mode off: used while blanking the screen. 556 * Use only with {@link SurfaceControl#setDisplayPowerMode}. 557 * @hide 558 */ 559 public static final int POWER_MODE_OFF = 0; 560 561 /** 562 * Display power mode doze: used while putting the screen into low power mode. 563 * Use only with {@link SurfaceControl#setDisplayPowerMode}. 564 * @hide 565 */ 566 public static final int POWER_MODE_DOZE = 1; 567 568 /** 569 * Display power mode normal: used while unblanking the screen. 570 * Use only with {@link SurfaceControl#setDisplayPowerMode}. 571 * @hide 572 */ 573 public static final int POWER_MODE_NORMAL = 2; 574 575 /** 576 * Display power mode doze: used while putting the screen into a suspended 577 * low power mode. Use only with {@link SurfaceControl#setDisplayPowerMode}. 578 * @hide 579 */ 580 public static final int POWER_MODE_DOZE_SUSPEND = 3; 581 582 /** 583 * Display power mode on: used while putting the screen into a suspended 584 * full power mode. Use only with {@link SurfaceControl#setDisplayPowerMode}. 585 * @hide 586 */ 587 public static final int POWER_MODE_ON_SUSPEND = 4; 588 589 /** 590 * internal representation of how to interpret pixel value, used only to convert to ColorSpace. 591 */ 592 private static final int INTERNAL_DATASPACE_SRGB = 142671872; 593 private static final int INTERNAL_DATASPACE_DISPLAY_P3 = 143261696; 594 private static final int INTERNAL_DATASPACE_SCRGB = 411107328; 595 assignNativeObject(long nativeObject, String callsite)596 private void assignNativeObject(long nativeObject, String callsite) { 597 if (mNativeObject != 0) { 598 release(); 599 } 600 if (nativeObject != 0) { 601 mCloseGuard.openWithCallSite("release", callsite); 602 } 603 mNativeObject = nativeObject; 604 mNativeHandle = mNativeObject != 0 ? nativeGetHandle(nativeObject) : 0; 605 } 606 607 /** 608 * @hide 609 */ copyFrom(@onNull SurfaceControl other, String callsite)610 public void copyFrom(@NonNull SurfaceControl other, String callsite) { 611 mName = other.mName; 612 mWidth = other.mWidth; 613 mHeight = other.mHeight; 614 mLocalOwnerView = other.mLocalOwnerView; 615 assignNativeObject(nativeCopyFromSurfaceControl(other.mNativeObject), callsite); 616 } 617 618 /** 619 * owner UID. 620 * @hide 621 */ 622 public static final int METADATA_OWNER_UID = 1; 623 624 /** 625 * Window type as per {@link WindowManager.LayoutParams}. 626 * @hide 627 */ 628 public static final int METADATA_WINDOW_TYPE = 2; 629 630 /** 631 * Task id to allow association between surfaces and task. 632 * @hide 633 */ 634 public static final int METADATA_TASK_ID = 3; 635 636 /** 637 * The style of mouse cursor and hotspot. 638 * @hide 639 */ 640 public static final int METADATA_MOUSE_CURSOR = 4; 641 642 /** 643 * Accessibility ID to allow association between surfaces and accessibility tree. 644 * @hide 645 */ 646 public static final int METADATA_ACCESSIBILITY_ID = 5; 647 648 /** 649 * owner PID. 650 * @hide 651 */ 652 public static final int METADATA_OWNER_PID = 6; 653 654 /** 655 * game mode for the layer - used for metrics 656 * @hide 657 */ 658 public static final int METADATA_GAME_MODE = 8; 659 660 /** 661 * A wrapper around HardwareBuffer that contains extra information about how to 662 * interpret the screenshot HardwareBuffer. 663 * 664 * @hide 665 */ 666 public static class ScreenshotHardwareBuffer { 667 private final HardwareBuffer mHardwareBuffer; 668 private final ColorSpace mColorSpace; 669 private final boolean mContainsSecureLayers; 670 ScreenshotHardwareBuffer(HardwareBuffer hardwareBuffer, ColorSpace colorSpace, boolean containsSecureLayers)671 public ScreenshotHardwareBuffer(HardwareBuffer hardwareBuffer, ColorSpace colorSpace, 672 boolean containsSecureLayers) { 673 mHardwareBuffer = hardwareBuffer; 674 mColorSpace = colorSpace; 675 mContainsSecureLayers = containsSecureLayers; 676 } 677 678 /** 679 * Create ScreenshotHardwareBuffer from an existing HardwareBuffer object. 680 * @param hardwareBuffer The existing HardwareBuffer object 681 * @param namedColorSpace Integer value of a named color space {@link ColorSpace.Named} 682 * @param containsSecureLayers Indicates whether this graphic buffer contains captured 683 * contents 684 * of secure layers, in which case the screenshot should not be persisted. 685 */ createFromNative(HardwareBuffer hardwareBuffer, int namedColorSpace, boolean containsSecureLayers)686 private static ScreenshotHardwareBuffer createFromNative(HardwareBuffer hardwareBuffer, 687 int namedColorSpace, boolean containsSecureLayers) { 688 ColorSpace colorSpace = ColorSpace.get(ColorSpace.Named.values()[namedColorSpace]); 689 return new ScreenshotHardwareBuffer(hardwareBuffer, colorSpace, containsSecureLayers); 690 } 691 getColorSpace()692 public ColorSpace getColorSpace() { 693 return mColorSpace; 694 } 695 getHardwareBuffer()696 public HardwareBuffer getHardwareBuffer() { 697 return mHardwareBuffer; 698 } 699 containsSecureLayers()700 public boolean containsSecureLayers() { 701 return mContainsSecureLayers; 702 } 703 704 /** 705 * Copy content of ScreenshotHardwareBuffer into a hardware bitmap and return it. 706 * Note: If you want to modify the Bitmap in software, you will need to copy the Bitmap 707 * into 708 * a software Bitmap using {@link Bitmap#copy(Bitmap.Config, boolean)} 709 * 710 * CAVEAT: This can be extremely slow; avoid use unless absolutely necessary; prefer to 711 * directly 712 * use the {@link HardwareBuffer} directly. 713 * 714 * @return Bitmap generated from the {@link HardwareBuffer} 715 */ asBitmap()716 public Bitmap asBitmap() { 717 if (mHardwareBuffer == null) { 718 Log.w(TAG, "Failed to take screenshot. Null screenshot object"); 719 return null; 720 } 721 return Bitmap.wrapHardwareBuffer(mHardwareBuffer, mColorSpace); 722 } 723 } 724 725 /** 726 * @hide 727 */ 728 public interface ScreenCaptureListener { 729 /** 730 * The callback invoked when the screen capture is complete. 731 * @param hardwareBuffer Data containing info about the screen capture. 732 */ onScreenCaptureComplete(ScreenshotHardwareBuffer hardwareBuffer)733 void onScreenCaptureComplete(ScreenshotHardwareBuffer hardwareBuffer); 734 } 735 736 private static class SyncScreenCaptureListener implements ScreenCaptureListener { 737 private static final int SCREENSHOT_WAIT_TIME_S = 1; 738 private ScreenshotHardwareBuffer mScreenshotHardwareBuffer; 739 private final CountDownLatch mCountDownLatch = new CountDownLatch(1); 740 741 @Override onScreenCaptureComplete(ScreenshotHardwareBuffer hardwareBuffer)742 public void onScreenCaptureComplete(ScreenshotHardwareBuffer hardwareBuffer) { 743 mScreenshotHardwareBuffer = hardwareBuffer; 744 mCountDownLatch.countDown(); 745 } 746 waitForScreenshot()747 private ScreenshotHardwareBuffer waitForScreenshot() { 748 try { 749 mCountDownLatch.await(SCREENSHOT_WAIT_TIME_S, TimeUnit.SECONDS); 750 } catch (Exception e) { 751 Log.e(TAG, "Failed to wait for screen capture result", e); 752 } 753 754 return mScreenshotHardwareBuffer; 755 } 756 } 757 758 /** 759 * A common arguments class used for various screenshot requests. This contains arguments that 760 * are shared between {@link DisplayCaptureArgs} and {@link LayerCaptureArgs} 761 * @hide 762 */ 763 private abstract static class CaptureArgs { 764 private final int mPixelFormat; 765 private final Rect mSourceCrop = new Rect(); 766 private final float mFrameScaleX; 767 private final float mFrameScaleY; 768 private final boolean mCaptureSecureLayers; 769 private final boolean mAllowProtected; 770 private final long mUid; 771 private final boolean mGrayscale; 772 CaptureArgs(Builder<? extends Builder<?>> builder)773 private CaptureArgs(Builder<? extends Builder<?>> builder) { 774 mPixelFormat = builder.mPixelFormat; 775 mSourceCrop.set(builder.mSourceCrop); 776 mFrameScaleX = builder.mFrameScaleX; 777 mFrameScaleY = builder.mFrameScaleY; 778 mCaptureSecureLayers = builder.mCaptureSecureLayers; 779 mAllowProtected = builder.mAllowProtected; 780 mUid = builder.mUid; 781 mGrayscale = builder.mGrayscale; 782 } 783 784 /** 785 * The Builder class used to construct {@link CaptureArgs} 786 * 787 * @param <T> A builder that extends {@link Builder} 788 */ 789 abstract static class Builder<T extends Builder<T>> { 790 private int mPixelFormat = PixelFormat.RGBA_8888; 791 private final Rect mSourceCrop = new Rect(); 792 private float mFrameScaleX = 1; 793 private float mFrameScaleY = 1; 794 private boolean mCaptureSecureLayers; 795 private boolean mAllowProtected; 796 private long mUid = -1; 797 private boolean mGrayscale; 798 799 /** 800 * The desired pixel format of the returned buffer. 801 */ setPixelFormat(int pixelFormat)802 public T setPixelFormat(int pixelFormat) { 803 mPixelFormat = pixelFormat; 804 return getThis(); 805 } 806 807 /** 808 * The portion of the screen to capture into the buffer. Caller may pass in 809 * 'new Rect()' if no cropping is desired. 810 */ setSourceCrop(Rect sourceCrop)811 public T setSourceCrop(Rect sourceCrop) { 812 mSourceCrop.set(sourceCrop); 813 return getThis(); 814 } 815 816 /** 817 * The desired scale of the returned buffer. The raw screen will be scaled up/down. 818 */ setFrameScale(float frameScale)819 public T setFrameScale(float frameScale) { 820 mFrameScaleX = frameScale; 821 mFrameScaleY = frameScale; 822 return getThis(); 823 } 824 825 /** 826 * The desired scale of the returned buffer, allowing separate values for x and y scale. 827 * The raw screen will be scaled up/down. 828 */ setFrameScale(float frameScaleX, float frameScaleY)829 public T setFrameScale(float frameScaleX, float frameScaleY) { 830 mFrameScaleX = frameScaleX; 831 mFrameScaleY = frameScaleY; 832 return getThis(); 833 } 834 835 /** 836 * Whether to allow the screenshot of secure layers. Warning: This should only be done 837 * if the content will be placed in a secure SurfaceControl. 838 * 839 * @see ScreenshotHardwareBuffer#containsSecureLayers() 840 */ setCaptureSecureLayers(boolean captureSecureLayers)841 public T setCaptureSecureLayers(boolean captureSecureLayers) { 842 mCaptureSecureLayers = captureSecureLayers; 843 return getThis(); 844 } 845 846 /** 847 * Whether to allow the screenshot of protected (DRM) content. Warning: The screenshot 848 * cannot be read in unprotected space. 849 * 850 * @see HardwareBuffer#USAGE_PROTECTED_CONTENT 851 */ setAllowProtected(boolean allowProtected)852 public T setAllowProtected(boolean allowProtected) { 853 mAllowProtected = allowProtected; 854 return getThis(); 855 } 856 857 /** 858 * Set the uid of the content that should be screenshot. The code will skip any surfaces 859 * that don't belong to the specified uid. 860 */ setUid(long uid)861 public T setUid(long uid) { 862 mUid = uid; 863 return getThis(); 864 } 865 866 /** 867 * Set whether the screenshot should use grayscale or not. 868 */ setGrayscale(boolean grayscale)869 public T setGrayscale(boolean grayscale) { 870 mGrayscale = grayscale; 871 return getThis(); 872 } 873 874 /** 875 * Each sub class should return itself to allow the builder to chain properly 876 */ getThis()877 abstract T getThis(); 878 } 879 } 880 881 /** 882 * The arguments class used to make display capture requests. 883 * 884 * @see #nativeCaptureDisplay(DisplayCaptureArgs, ScreenCaptureListener) 885 * @hide 886 */ 887 public static class DisplayCaptureArgs extends CaptureArgs { 888 private final IBinder mDisplayToken; 889 private final int mWidth; 890 private final int mHeight; 891 private final boolean mUseIdentityTransform; 892 DisplayCaptureArgs(Builder builder)893 private DisplayCaptureArgs(Builder builder) { 894 super(builder); 895 mDisplayToken = builder.mDisplayToken; 896 mWidth = builder.mWidth; 897 mHeight = builder.mHeight; 898 mUseIdentityTransform = builder.mUseIdentityTransform; 899 } 900 901 /** 902 * The Builder class used to construct {@link DisplayCaptureArgs} 903 */ 904 public static class Builder extends CaptureArgs.Builder<Builder> { 905 private IBinder mDisplayToken; 906 private int mWidth; 907 private int mHeight; 908 private boolean mUseIdentityTransform; 909 910 /** 911 * Construct a new {@link LayerCaptureArgs} with the set parameters. The builder 912 * remains valid. 913 */ build()914 public DisplayCaptureArgs build() { 915 if (mDisplayToken == null) { 916 throw new IllegalStateException( 917 "Can't take screenshot with null display token"); 918 } 919 return new DisplayCaptureArgs(this); 920 } 921 Builder(IBinder displayToken)922 public Builder(IBinder displayToken) { 923 setDisplayToken(displayToken); 924 } 925 926 /** 927 * The display to take the screenshot of. 928 */ setDisplayToken(IBinder displayToken)929 public Builder setDisplayToken(IBinder displayToken) { 930 mDisplayToken = displayToken; 931 return this; 932 } 933 934 /** 935 * Set the desired size of the returned buffer. The raw screen will be scaled down to 936 * this size 937 * 938 * @param width The desired width of the returned buffer. Caller may pass in 0 if no 939 * scaling is desired. 940 * @param height The desired height of the returned buffer. Caller may pass in 0 if no 941 * scaling is desired. 942 */ setSize(int width, int height)943 public Builder setSize(int width, int height) { 944 mWidth = width; 945 mHeight = height; 946 return this; 947 } 948 949 /** 950 * Replace the rotation transform of the display with the identity transformation while 951 * taking the screenshot. This ensures the screenshot is taken in the ROTATION_0 952 * orientation. Set this value to false if the screenshot should be taken in the 953 * current screen orientation. 954 */ setUseIdentityTransform(boolean useIdentityTransform)955 public Builder setUseIdentityTransform(boolean useIdentityTransform) { 956 mUseIdentityTransform = useIdentityTransform; 957 return this; 958 } 959 960 @Override getThis()961 Builder getThis() { 962 return this; 963 } 964 } 965 } 966 967 /** 968 * The arguments class used to make layer capture requests. 969 * 970 * @see #nativeCaptureLayers(LayerCaptureArgs, ScreenCaptureListener) 971 * @hide 972 */ 973 public static class LayerCaptureArgs extends CaptureArgs { 974 private final long mNativeLayer; 975 private final long[] mNativeExcludeLayers; 976 private final boolean mChildrenOnly; 977 LayerCaptureArgs(Builder builder)978 private LayerCaptureArgs(Builder builder) { 979 super(builder); 980 mChildrenOnly = builder.mChildrenOnly; 981 mNativeLayer = builder.mLayer.mNativeObject; 982 if (builder.mExcludeLayers != null) { 983 mNativeExcludeLayers = new long[builder.mExcludeLayers.length]; 984 for (int i = 0; i < builder.mExcludeLayers.length; i++) { 985 mNativeExcludeLayers[i] = builder.mExcludeLayers[i].mNativeObject; 986 } 987 } else { 988 mNativeExcludeLayers = null; 989 } 990 } 991 992 /** 993 * The Builder class used to construct {@link LayerCaptureArgs} 994 */ 995 public static class Builder extends CaptureArgs.Builder<Builder> { 996 private SurfaceControl mLayer; 997 private SurfaceControl[] mExcludeLayers; 998 private boolean mChildrenOnly = true; 999 1000 /** 1001 * Construct a new {@link LayerCaptureArgs} with the set parameters. The builder 1002 * remains valid. 1003 */ build()1004 public LayerCaptureArgs build() { 1005 if (mLayer == null) { 1006 throw new IllegalStateException( 1007 "Can't take screenshot with null layer"); 1008 } 1009 return new LayerCaptureArgs(this); 1010 } 1011 Builder(SurfaceControl layer)1012 public Builder(SurfaceControl layer) { 1013 setLayer(layer); 1014 } 1015 1016 /** 1017 * The root layer to capture. 1018 */ setLayer(SurfaceControl layer)1019 public Builder setLayer(SurfaceControl layer) { 1020 mLayer = layer; 1021 return this; 1022 } 1023 1024 1025 /** 1026 * An array of layer handles to exclude. 1027 */ setExcludeLayers(@ullable SurfaceControl[] excludeLayers)1028 public Builder setExcludeLayers(@Nullable SurfaceControl[] excludeLayers) { 1029 mExcludeLayers = excludeLayers; 1030 return this; 1031 } 1032 1033 /** 1034 * Whether to include the layer itself in the screenshot or just the children and their 1035 * descendants. 1036 */ setChildrenOnly(boolean childrenOnly)1037 public Builder setChildrenOnly(boolean childrenOnly) { 1038 mChildrenOnly = childrenOnly; 1039 return this; 1040 } 1041 1042 @Override getThis()1043 Builder getThis() { 1044 return this; 1045 } 1046 1047 } 1048 } 1049 1050 /** 1051 * Builder class for {@link SurfaceControl} objects. 1052 * 1053 * By default the surface will be hidden, and have "unset" bounds, meaning it can 1054 * be as large as the bounds of its parent if a buffer or child so requires. 1055 * 1056 * It is necessary to set at least a name via {@link Builder#setName} 1057 */ 1058 public static class Builder { 1059 private SurfaceSession mSession; 1060 private int mFlags = HIDDEN; 1061 private int mWidth; 1062 private int mHeight; 1063 private int mFormat = PixelFormat.OPAQUE; 1064 private String mName; 1065 private WeakReference<View> mLocalOwnerView; 1066 private SurfaceControl mParent; 1067 private SparseIntArray mMetadata; 1068 private String mCallsite = "SurfaceControl.Builder"; 1069 1070 /** 1071 * Begin building a SurfaceControl with a given {@link SurfaceSession}. 1072 * 1073 * @param session The {@link SurfaceSession} with which to eventually construct the surface. 1074 * @hide 1075 */ Builder(SurfaceSession session)1076 public Builder(SurfaceSession session) { 1077 mSession = session; 1078 } 1079 1080 /** 1081 * Begin building a SurfaceControl. 1082 */ Builder()1083 public Builder() { 1084 } 1085 1086 /** 1087 * Construct a new {@link SurfaceControl} with the set parameters. The builder 1088 * remains valid. 1089 */ 1090 @NonNull build()1091 public SurfaceControl build() { 1092 if (mWidth < 0 || mHeight < 0) { 1093 throw new IllegalStateException( 1094 "width and height must be positive or unset"); 1095 } 1096 if ((mWidth > 0 || mHeight > 0) && (isEffectLayer() || isContainerLayer())) { 1097 throw new IllegalStateException( 1098 "Only buffer layers can set a valid buffer size."); 1099 } 1100 1101 if ((mFlags & FX_SURFACE_MASK) == FX_SURFACE_NORMAL) { 1102 setBLASTLayer(); 1103 } 1104 1105 return new SurfaceControl( 1106 mSession, mName, mWidth, mHeight, mFormat, mFlags, mParent, mMetadata, 1107 mLocalOwnerView, mCallsite); 1108 } 1109 1110 /** 1111 * Set a debugging-name for the SurfaceControl. 1112 * 1113 * @param name A name to identify the Surface in debugging. 1114 */ 1115 @NonNull setName(@onNull String name)1116 public Builder setName(@NonNull String name) { 1117 mName = name; 1118 return this; 1119 } 1120 1121 /** 1122 * Set the local owner view for the surface. This view is only 1123 * valid in the same process and is not transferred in an IPC. 1124 * 1125 * Note: This is used for cases where we want to know the view 1126 * that manages the surface control while intercepting reparenting. 1127 * A specific example is InlineContentView which exposes is surface 1128 * control for reparenting as a way to implement clipping of several 1129 * InlineContentView instances within a certain area. 1130 * 1131 * @param view The owner view. 1132 * @return This builder. 1133 * 1134 * @hide 1135 */ 1136 @NonNull setLocalOwnerView(@onNull View view)1137 public Builder setLocalOwnerView(@NonNull View view) { 1138 mLocalOwnerView = new WeakReference<>(view); 1139 return this; 1140 } 1141 1142 /** 1143 * Set the initial size of the controlled surface's buffers in pixels. 1144 * 1145 * @param width The buffer width in pixels. 1146 * @param height The buffer height in pixels. 1147 */ 1148 @NonNull setBufferSize(@ntRangefrom = 0) int width, @IntRange(from = 0) int height)1149 public Builder setBufferSize(@IntRange(from = 0) int width, 1150 @IntRange(from = 0) int height) { 1151 if (width < 0 || height < 0) { 1152 throw new IllegalArgumentException( 1153 "width and height must be positive"); 1154 } 1155 mWidth = width; 1156 mHeight = height; 1157 // set this as a buffer layer since we are specifying a buffer size. 1158 return setFlags(FX_SURFACE_NORMAL, FX_SURFACE_MASK); 1159 } 1160 unsetBufferSize()1161 private void unsetBufferSize() { 1162 mWidth = 0; 1163 mHeight = 0; 1164 } 1165 1166 /** 1167 * Set the pixel format of the controlled surface's buffers, using constants from 1168 * {@link android.graphics.PixelFormat}. 1169 */ 1170 @NonNull setFormat(@ixelFormat.Format int format)1171 public Builder setFormat(@PixelFormat.Format int format) { 1172 mFormat = format; 1173 return this; 1174 } 1175 1176 /** 1177 * Specify if the app requires a hardware-protected path to 1178 * an external display sync. If protected content is enabled, but 1179 * such a path is not available, then the controlled Surface will 1180 * not be displayed. 1181 * 1182 * @param protectedContent Whether to require a protected sink. 1183 * @hide 1184 */ 1185 @NonNull setProtected(boolean protectedContent)1186 public Builder setProtected(boolean protectedContent) { 1187 if (protectedContent) { 1188 mFlags |= PROTECTED_APP; 1189 } else { 1190 mFlags &= ~PROTECTED_APP; 1191 } 1192 return this; 1193 } 1194 1195 /** 1196 * Specify whether the Surface contains secure content. If true, the system 1197 * will prevent the surfaces content from being copied by another process. In 1198 * particular screenshots and VNC servers will be disabled. This is however 1199 * not a complete prevention of readback as {@link #setProtected}. 1200 * @hide 1201 */ 1202 @NonNull setSecure(boolean secure)1203 public Builder setSecure(boolean secure) { 1204 if (secure) { 1205 mFlags |= SECURE; 1206 } else { 1207 mFlags &= ~SECURE; 1208 } 1209 return this; 1210 } 1211 1212 /** 1213 * Indicates whether the surface must be considered opaque, 1214 * even if its pixel format is set to translucent. This can be useful if an 1215 * application needs full RGBA 8888 support for instance but will 1216 * still draw every pixel opaque. 1217 * <p> 1218 * This flag only determines whether opacity will be sampled from the alpha channel. 1219 * Plane-alpha from calls to setAlpha() can still result in blended composition 1220 * regardless of the opaque setting. 1221 * 1222 * Combined effects are (assuming a buffer format with an alpha channel): 1223 * <ul> 1224 * <li>OPAQUE + alpha(1.0) == opaque composition 1225 * <li>OPAQUE + alpha(0.x) == blended composition 1226 * <li>OPAQUE + alpha(0.0) == no composition 1227 * <li>!OPAQUE + alpha(1.0) == blended composition 1228 * <li>!OPAQUE + alpha(0.x) == blended composition 1229 * <li>!OPAQUE + alpha(0.0) == no composition 1230 * </ul> 1231 * If the underlying buffer lacks an alpha channel, it is as if setOpaque(true) 1232 * were set automatically. 1233 * @param opaque Whether the Surface is OPAQUE. 1234 */ 1235 @NonNull setOpaque(boolean opaque)1236 public Builder setOpaque(boolean opaque) { 1237 if (opaque) { 1238 mFlags |= OPAQUE; 1239 } else { 1240 mFlags &= ~OPAQUE; 1241 } 1242 return this; 1243 } 1244 1245 /** 1246 * Set the initial visibility for the SurfaceControl. 1247 * 1248 * @param hidden Whether the Surface is initially HIDDEN. 1249 * @hide 1250 */ 1251 @NonNull setHidden(boolean hidden)1252 public Builder setHidden(boolean hidden) { 1253 if (hidden) { 1254 mFlags |= HIDDEN; 1255 } else { 1256 mFlags &= ~HIDDEN; 1257 } 1258 return this; 1259 } 1260 1261 /** 1262 * Set a parent surface for our new SurfaceControl. 1263 * 1264 * Child surfaces are constrained to the onscreen region of their parent. 1265 * Furthermore they stack relatively in Z order, and inherit the transformation 1266 * of the parent. 1267 * 1268 * @param parent The parent control. 1269 */ 1270 @NonNull setParent(@ullable SurfaceControl parent)1271 public Builder setParent(@Nullable SurfaceControl parent) { 1272 mParent = parent; 1273 return this; 1274 } 1275 1276 /** 1277 * Sets a metadata int. 1278 * 1279 * @param key metadata key 1280 * @param data associated data 1281 * @hide 1282 */ setMetadata(int key, int data)1283 public Builder setMetadata(int key, int data) { 1284 if (mMetadata == null) { 1285 mMetadata = new SparseIntArray(); 1286 } 1287 mMetadata.put(key, data); 1288 return this; 1289 } 1290 1291 /** 1292 * Indicate whether an 'EffectLayer' is to be constructed. 1293 * 1294 * An effect layer behaves like a container layer by default but it can support 1295 * color fill, shadows and/or blur. These layers will not have an associated buffer. 1296 * When created, this layer has no effects set and will be transparent but the caller 1297 * can render an effect by calling: 1298 * - {@link Transaction#setColor(SurfaceControl, float[])} 1299 * - {@link Transaction#setBackgroundBlurRadius(SurfaceControl, int)} 1300 * - {@link Transaction#setShadowRadius(SurfaceControl, float)} 1301 * 1302 * @hide 1303 */ setEffectLayer()1304 public Builder setEffectLayer() { 1305 mFlags |= NO_COLOR_FILL; 1306 unsetBufferSize(); 1307 return setFlags(FX_SURFACE_EFFECT, FX_SURFACE_MASK); 1308 } 1309 1310 /** 1311 * A convenience function to create an effect layer with a default color fill 1312 * applied to it. Currently that color is black. 1313 * 1314 * @hide 1315 */ setColorLayer()1316 public Builder setColorLayer() { 1317 unsetBufferSize(); 1318 return setFlags(FX_SURFACE_EFFECT, FX_SURFACE_MASK); 1319 } 1320 isEffectLayer()1321 private boolean isEffectLayer() { 1322 return (mFlags & FX_SURFACE_EFFECT) == FX_SURFACE_EFFECT; 1323 } 1324 1325 /** 1326 * @hide 1327 */ setBLASTLayer()1328 public Builder setBLASTLayer() { 1329 return setFlags(FX_SURFACE_BLAST, FX_SURFACE_MASK); 1330 } 1331 1332 /** 1333 * Indicates whether a 'ContainerLayer' is to be constructed. 1334 * 1335 * Container layers will not be rendered in any fashion and instead are used 1336 * as a parent of renderable layers. 1337 * 1338 * @hide 1339 */ setContainerLayer()1340 public Builder setContainerLayer() { 1341 unsetBufferSize(); 1342 return setFlags(FX_SURFACE_CONTAINER, FX_SURFACE_MASK); 1343 } 1344 isContainerLayer()1345 private boolean isContainerLayer() { 1346 return (mFlags & FX_SURFACE_CONTAINER) == FX_SURFACE_CONTAINER; 1347 } 1348 1349 /** 1350 * Set 'Surface creation flags' such as {@link #HIDDEN}, {@link #SECURE}. 1351 * 1352 * TODO: Finish conversion to individual builder methods? 1353 * @param flags The combined flags 1354 * @hide 1355 */ setFlags(int flags)1356 public Builder setFlags(int flags) { 1357 mFlags = flags; 1358 return this; 1359 } 1360 1361 /** 1362 * Sets the callsite this SurfaceControl is constructed from. 1363 * 1364 * @param callsite String uniquely identifying callsite that created this object. Used for 1365 * leakage tracking. 1366 * @hide 1367 */ setCallsite(String callsite)1368 public Builder setCallsite(String callsite) { 1369 mCallsite = callsite; 1370 return this; 1371 } 1372 setFlags(int flags, int mask)1373 private Builder setFlags(int flags, int mask) { 1374 mFlags = (mFlags & ~mask) | flags; 1375 return this; 1376 } 1377 } 1378 1379 /** 1380 * Create a surface with a name. 1381 * <p> 1382 * The surface creation flags specify what kind of surface to create and 1383 * certain options such as whether the surface can be assumed to be opaque 1384 * and whether it should be initially hidden. Surfaces should always be 1385 * created with the {@link #HIDDEN} flag set to ensure that they are not 1386 * made visible prematurely before all of the surface's properties have been 1387 * configured. 1388 * <p> 1389 * Good practice is to first create the surface with the {@link #HIDDEN} flag 1390 * specified, open a transaction, set the surface layer, layer stack, alpha, 1391 * and position, call {@link Transaction#show(SurfaceControl)} if appropriate, and close the 1392 * transaction. 1393 * <p> 1394 * Bounds of the surface is determined by its crop and its buffer size. If the 1395 * surface has no buffer or crop, the surface is boundless and only constrained 1396 * by the size of its parent bounds. 1397 * 1398 * @param session The surface session, must not be null. 1399 * @param name The surface name, must not be null. 1400 * @param w The surface initial width. 1401 * @param h The surface initial height. 1402 * @param flags The surface creation flags. 1403 * @param metadata Initial metadata. 1404 * @param callsite String uniquely identifying callsite that created this object. Used for 1405 * leakage tracking. 1406 * @throws throws OutOfResourcesException If the SurfaceControl cannot be created. 1407 */ SurfaceControl(SurfaceSession session, String name, int w, int h, int format, int flags, SurfaceControl parent, SparseIntArray metadata, WeakReference<View> localOwnerView, String callsite)1408 private SurfaceControl(SurfaceSession session, String name, int w, int h, int format, int flags, 1409 SurfaceControl parent, SparseIntArray metadata, WeakReference<View> localOwnerView, 1410 String callsite) 1411 throws OutOfResourcesException, IllegalArgumentException { 1412 if (name == null) { 1413 throw new IllegalArgumentException("name must not be null"); 1414 } 1415 1416 mName = name; 1417 mWidth = w; 1418 mHeight = h; 1419 mLocalOwnerView = localOwnerView; 1420 Parcel metaParcel = Parcel.obtain(); 1421 try { 1422 if (metadata != null && metadata.size() > 0) { 1423 metaParcel.writeInt(metadata.size()); 1424 for (int i = 0; i < metadata.size(); ++i) { 1425 metaParcel.writeInt(metadata.keyAt(i)); 1426 metaParcel.writeByteArray( 1427 ByteBuffer.allocate(4).order(ByteOrder.nativeOrder()) 1428 .putInt(metadata.valueAt(i)).array()); 1429 } 1430 metaParcel.setDataPosition(0); 1431 } 1432 mNativeObject = nativeCreate(session, name, w, h, format, flags, 1433 parent != null ? parent.mNativeObject : 0, metaParcel); 1434 } finally { 1435 metaParcel.recycle(); 1436 } 1437 if (mNativeObject == 0) { 1438 throw new OutOfResourcesException( 1439 "Couldn't allocate SurfaceControl native object"); 1440 } 1441 mNativeHandle = nativeGetHandle(mNativeObject); 1442 mCloseGuard.openWithCallSite("release", callsite); 1443 } 1444 1445 /** 1446 * Copy constructor. Creates a new native object pointing to the same surface as {@code other}. 1447 * 1448 * @param other The object to copy the surface from. 1449 * @param callsite String uniquely identifying callsite that created this object. Used for 1450 * leakage tracking. 1451 * @hide 1452 */ 1453 @TestApi SurfaceControl(@onNull SurfaceControl other, @NonNull String callsite)1454 public SurfaceControl(@NonNull SurfaceControl other, @NonNull String callsite) { 1455 copyFrom(other, callsite); 1456 } 1457 SurfaceControl(Parcel in)1458 private SurfaceControl(Parcel in) { 1459 readFromParcel(in); 1460 } 1461 1462 /** 1463 * @hide 1464 */ SurfaceControl()1465 public SurfaceControl() { 1466 } 1467 readFromParcel(Parcel in)1468 public void readFromParcel(Parcel in) { 1469 if (in == null) { 1470 throw new IllegalArgumentException("source must not be null"); 1471 } 1472 1473 mName = in.readString8(); 1474 mWidth = in.readInt(); 1475 mHeight = in.readInt(); 1476 1477 long object = 0; 1478 if (in.readInt() != 0) { 1479 object = nativeReadFromParcel(in); 1480 } 1481 assignNativeObject(object, "readFromParcel"); 1482 } 1483 1484 @Override describeContents()1485 public int describeContents() { 1486 return 0; 1487 } 1488 1489 @Override writeToParcel(Parcel dest, int flags)1490 public void writeToParcel(Parcel dest, int flags) { 1491 dest.writeString8(mName); 1492 dest.writeInt(mWidth); 1493 dest.writeInt(mHeight); 1494 if (mNativeObject == 0) { 1495 dest.writeInt(0); 1496 } else { 1497 dest.writeInt(1); 1498 } 1499 nativeWriteToParcel(mNativeObject, dest); 1500 1501 if ((flags & Parcelable.PARCELABLE_WRITE_RETURN_VALUE) != 0) { 1502 release(); 1503 } 1504 } 1505 1506 /** 1507 * Checks whether two {@link SurfaceControl} objects represent the same surface. 1508 * 1509 * @param other The other object to check 1510 * @return {@code true} if these two {@link SurfaceControl} objects represent the same surface. 1511 * @hide 1512 */ 1513 @TestApi isSameSurface(@onNull SurfaceControl other)1514 public boolean isSameSurface(@NonNull SurfaceControl other) { 1515 return other.mNativeHandle == mNativeHandle; 1516 } 1517 1518 /** 1519 * Write to a protocol buffer output stream. Protocol buffer message definition is at {@link 1520 * android.view.SurfaceControlProto}. 1521 * 1522 * @param proto Stream to write the SurfaceControl object to. 1523 * @param fieldId Field Id of the SurfaceControl as defined in the parent message. 1524 * @hide 1525 */ dumpDebug(ProtoOutputStream proto, long fieldId)1526 public void dumpDebug(ProtoOutputStream proto, long fieldId) { 1527 final long token = proto.start(fieldId); 1528 proto.write(HASH_CODE, System.identityHashCode(this)); 1529 proto.write(NAME, mName); 1530 proto.end(token); 1531 } 1532 1533 public static final @android.annotation.NonNull Creator<SurfaceControl> CREATOR 1534 = new Creator<SurfaceControl>() { 1535 public SurfaceControl createFromParcel(Parcel in) { 1536 return new SurfaceControl(in); 1537 } 1538 1539 public SurfaceControl[] newArray(int size) { 1540 return new SurfaceControl[size]; 1541 } 1542 }; 1543 1544 /** 1545 * @hide 1546 */ 1547 @Override finalize()1548 protected void finalize() throws Throwable { 1549 try { 1550 if (mCloseGuard != null) { 1551 mCloseGuard.warnIfOpen(); 1552 } 1553 if (mNativeObject != 0) { 1554 nativeRelease(mNativeObject); 1555 } 1556 } finally { 1557 super.finalize(); 1558 } 1559 } 1560 1561 /** 1562 * Release the local reference to the server-side surface. The surface 1563 * may continue to exist on-screen as long as its parent continues 1564 * to exist. To explicitly remove a surface from the screen use 1565 * {@link Transaction#reparent} with a null-parent. After release, 1566 * {@link #isValid} will return false and other methods will throw 1567 * an exception. 1568 * 1569 * Always call release() when you're done with a SurfaceControl. 1570 */ release()1571 public void release() { 1572 if (mNativeObject != 0) { 1573 nativeRelease(mNativeObject); 1574 mNativeObject = 0; 1575 mNativeHandle = 0; 1576 mCloseGuard.close(); 1577 } 1578 } 1579 1580 /** 1581 * Disconnect any client still connected to the surface. 1582 * @hide 1583 */ disconnect()1584 public void disconnect() { 1585 if (mNativeObject != 0) { 1586 nativeDisconnect(mNativeObject); 1587 } 1588 } 1589 checkNotReleased()1590 private void checkNotReleased() { 1591 if (mNativeObject == 0) throw new NullPointerException( 1592 "Invalid " + this + ", mNativeObject is null. Have you called release() already?"); 1593 } 1594 1595 /** 1596 * Check whether this instance points to a valid layer with the system-compositor. For 1597 * example this may be false if construction failed, or the layer was released 1598 * ({@link #release}). 1599 * 1600 * @return Whether this SurfaceControl is valid. 1601 */ isValid()1602 public boolean isValid() { 1603 return mNativeObject != 0; 1604 } 1605 1606 /* 1607 * set surface parameters. 1608 * needs to be inside open/closeTransaction block 1609 */ 1610 1611 /** start a transaction 1612 * @hide 1613 */ 1614 @UnsupportedAppUsage openTransaction()1615 public static void openTransaction() { 1616 synchronized (SurfaceControl.class) { 1617 if (sGlobalTransaction == null) { 1618 sGlobalTransaction = new GlobalTransactionWrapper(); 1619 } 1620 synchronized(SurfaceControl.class) { 1621 sTransactionNestCount++; 1622 } 1623 } 1624 } 1625 1626 /** 1627 * Merge the supplied transaction in to the deprecated "global" transaction. 1628 * This clears the supplied transaction in an identical fashion to {@link Transaction#merge}. 1629 * <p> 1630 * This is a utility for interop with legacy-code and will go away with the Global Transaction. 1631 * @hide 1632 */ 1633 @Deprecated mergeToGlobalTransaction(Transaction t)1634 public static void mergeToGlobalTransaction(Transaction t) { 1635 synchronized(SurfaceControl.class) { 1636 sGlobalTransaction.merge(t); 1637 } 1638 } 1639 1640 /** end a transaction 1641 * @hide 1642 */ 1643 @UnsupportedAppUsage closeTransaction()1644 public static void closeTransaction() { 1645 synchronized(SurfaceControl.class) { 1646 if (sTransactionNestCount == 0) { 1647 Log.e(TAG, 1648 "Call to SurfaceControl.closeTransaction without matching openTransaction"); 1649 } else if (--sTransactionNestCount > 0) { 1650 return; 1651 } 1652 sGlobalTransaction.applyGlobalTransaction(false); 1653 } 1654 } 1655 1656 /** 1657 * @hide 1658 */ clearContentFrameStats()1659 public boolean clearContentFrameStats() { 1660 checkNotReleased(); 1661 return nativeClearContentFrameStats(mNativeObject); 1662 } 1663 1664 /** 1665 * @hide 1666 */ getContentFrameStats(WindowContentFrameStats outStats)1667 public boolean getContentFrameStats(WindowContentFrameStats outStats) { 1668 checkNotReleased(); 1669 return nativeGetContentFrameStats(mNativeObject, outStats); 1670 } 1671 1672 /** 1673 * @hide 1674 */ clearAnimationFrameStats()1675 public static boolean clearAnimationFrameStats() { 1676 return nativeClearAnimationFrameStats(); 1677 } 1678 1679 /** 1680 * @hide 1681 */ getAnimationFrameStats(WindowAnimationFrameStats outStats)1682 public static boolean getAnimationFrameStats(WindowAnimationFrameStats outStats) { 1683 return nativeGetAnimationFrameStats(outStats); 1684 } 1685 1686 /** 1687 * @hide 1688 */ getWidth()1689 public int getWidth() { 1690 synchronized (mLock) { 1691 return mWidth; 1692 } 1693 } 1694 1695 /** 1696 * @hide 1697 */ getHeight()1698 public int getHeight() { 1699 synchronized (mLock) { 1700 return mHeight; 1701 } 1702 } 1703 1704 /** 1705 * Gets the local view that owns this surface. 1706 * 1707 * @return The owner view. 1708 * 1709 * @hide 1710 */ getLocalOwnerView()1711 public @Nullable View getLocalOwnerView() { 1712 return (mLocalOwnerView != null) ? mLocalOwnerView.get() : null; 1713 } 1714 1715 @Override toString()1716 public String toString() { 1717 return "Surface(name=" + mName + ")/@0x" + 1718 Integer.toHexString(System.identityHashCode(this)); 1719 } 1720 1721 /** 1722 * Immutable information about physical display. 1723 * 1724 * @hide 1725 */ 1726 public static final class StaticDisplayInfo { 1727 public boolean isInternal; 1728 public float density; 1729 public boolean secure; 1730 public DeviceProductInfo deviceProductInfo; 1731 1732 @Override toString()1733 public String toString() { 1734 return "StaticDisplayInfo{isInternal=" + isInternal 1735 + ", density=" + density 1736 + ", secure=" + secure 1737 + ", deviceProductInfo=" + deviceProductInfo + "}"; 1738 } 1739 1740 @Override equals(@ullable Object o)1741 public boolean equals(@Nullable Object o) { 1742 if (this == o) return true; 1743 if (o == null || getClass() != o.getClass()) return false; 1744 StaticDisplayInfo that = (StaticDisplayInfo) o; 1745 return isInternal == that.isInternal 1746 && density == that.density 1747 && secure == that.secure 1748 && Objects.equals(deviceProductInfo, that.deviceProductInfo); 1749 } 1750 1751 @Override hashCode()1752 public int hashCode() { 1753 return Objects.hash(isInternal, density, secure, deviceProductInfo); 1754 } 1755 } 1756 1757 /** 1758 * Dynamic information about physical display. 1759 * 1760 * @hide 1761 */ 1762 public static final class DynamicDisplayInfo { 1763 public DisplayMode[] supportedDisplayModes; 1764 public int activeDisplayModeId; 1765 1766 public int[] supportedColorModes; 1767 public int activeColorMode; 1768 1769 public Display.HdrCapabilities hdrCapabilities; 1770 1771 public boolean autoLowLatencyModeSupported; 1772 public boolean gameContentTypeSupported; 1773 1774 @Override toString()1775 public String toString() { 1776 return "DynamicDisplayInfo{" 1777 + "supportedDisplayModes=" + Arrays.toString(supportedDisplayModes) 1778 + ", activeDisplayModeId=" + activeDisplayModeId 1779 + ", supportedColorModes=" + Arrays.toString(supportedColorModes) 1780 + ", activeColorMode=" + activeColorMode 1781 + ", hdrCapabilities=" + hdrCapabilities 1782 + ", autoLowLatencyModeSupported=" + autoLowLatencyModeSupported 1783 + ", gameContentTypeSupported" + gameContentTypeSupported + "}"; 1784 } 1785 1786 @Override equals(@ullable Object o)1787 public boolean equals(@Nullable Object o) { 1788 if (this == o) return true; 1789 if (o == null || getClass() != o.getClass()) return false; 1790 DynamicDisplayInfo that = (DynamicDisplayInfo) o; 1791 return Arrays.equals(supportedDisplayModes, that.supportedDisplayModes) 1792 && activeDisplayModeId == that.activeDisplayModeId 1793 && Arrays.equals(supportedColorModes, that.supportedColorModes) 1794 && activeColorMode == that.activeColorMode 1795 && Objects.equals(hdrCapabilities, that.hdrCapabilities); 1796 } 1797 1798 @Override hashCode()1799 public int hashCode() { 1800 return Objects.hash(supportedDisplayModes, activeDisplayModeId, activeDisplayModeId, 1801 activeColorMode, hdrCapabilities); 1802 } 1803 } 1804 1805 /** 1806 * Configuration supported by physical display. 1807 * 1808 * @hide 1809 */ 1810 public static final class DisplayMode { 1811 /** 1812 * Invalid display config id. 1813 */ 1814 public static final int INVALID_DISPLAY_MODE_ID = -1; 1815 1816 public int id; 1817 public int width; 1818 public int height; 1819 public float xDpi; 1820 public float yDpi; 1821 1822 public float refreshRate; 1823 public long appVsyncOffsetNanos; 1824 public long presentationDeadlineNanos; 1825 1826 /** 1827 * The config group ID this config is associated to. 1828 * Configs in the same group are similar from vendor's perspective and switching between 1829 * configs within the same group can be done seamlessly in most cases. 1830 * @see: android.hardware.graphics.composer@2.4::IComposerClient::Attribute::CONFIG_GROUP 1831 */ 1832 public int group; 1833 1834 @Override toString()1835 public String toString() { 1836 return "DisplayMode{id=" + id 1837 + ", width=" + width 1838 + ", height=" + height 1839 + ", xDpi=" + xDpi 1840 + ", yDpi=" + yDpi 1841 + ", refreshRate=" + refreshRate 1842 + ", appVsyncOffsetNanos=" + appVsyncOffsetNanos 1843 + ", presentationDeadlineNanos=" + presentationDeadlineNanos 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.refreshRate, refreshRate) == 0 1858 && appVsyncOffsetNanos == that.appVsyncOffsetNanos 1859 && presentationDeadlineNanos == that.presentationDeadlineNanos 1860 && group == that.group; 1861 } 1862 1863 @Override hashCode()1864 public int hashCode() { 1865 return Objects.hash(id, width, height, xDpi, yDpi, refreshRate, appVsyncOffsetNanos, 1866 presentationDeadlineNanos, group); 1867 } 1868 } 1869 1870 /** 1871 * @hide 1872 */ setDisplayPowerMode(IBinder displayToken, int mode)1873 public static void setDisplayPowerMode(IBinder displayToken, int mode) { 1874 if (displayToken == null) { 1875 throw new IllegalArgumentException("displayToken must not be null"); 1876 } 1877 nativeSetDisplayPowerMode(displayToken, mode); 1878 } 1879 1880 /** 1881 * @hide 1882 */ getStaticDisplayInfo(IBinder displayToken)1883 public static StaticDisplayInfo getStaticDisplayInfo(IBinder displayToken) { 1884 if (displayToken == null) { 1885 throw new IllegalArgumentException("displayToken must not be null"); 1886 } 1887 return nativeGetStaticDisplayInfo(displayToken); 1888 } 1889 1890 /** 1891 * @hide 1892 */ getDynamicDisplayInfo(IBinder displayToken)1893 public static DynamicDisplayInfo getDynamicDisplayInfo(IBinder displayToken) { 1894 if (displayToken == null) { 1895 throw new IllegalArgumentException("displayToken must not be null"); 1896 } 1897 return nativeGetDynamicDisplayInfo(displayToken); 1898 } 1899 1900 /** 1901 * @hide 1902 */ getDisplayedContentSamplingAttributes( IBinder displayToken)1903 public static DisplayedContentSamplingAttributes getDisplayedContentSamplingAttributes( 1904 IBinder displayToken) { 1905 if (displayToken == null) { 1906 throw new IllegalArgumentException("displayToken must not be null"); 1907 } 1908 return nativeGetDisplayedContentSamplingAttributes(displayToken); 1909 } 1910 1911 /** 1912 * @hide 1913 */ setDisplayedContentSamplingEnabled( IBinder displayToken, boolean enable, int componentMask, int maxFrames)1914 public static boolean setDisplayedContentSamplingEnabled( 1915 IBinder displayToken, boolean enable, int componentMask, int maxFrames) { 1916 if (displayToken == null) { 1917 throw new IllegalArgumentException("displayToken must not be null"); 1918 } 1919 final int maxColorComponents = 4; 1920 if ((componentMask >> maxColorComponents) != 0) { 1921 throw new IllegalArgumentException("invalid componentMask when enabling sampling"); 1922 } 1923 return nativeSetDisplayedContentSamplingEnabled( 1924 displayToken, enable, componentMask, maxFrames); 1925 } 1926 1927 /** 1928 * @hide 1929 */ getDisplayedContentSample( IBinder displayToken, long maxFrames, long timestamp)1930 public static DisplayedContentSample getDisplayedContentSample( 1931 IBinder displayToken, long maxFrames, long timestamp) { 1932 if (displayToken == null) { 1933 throw new IllegalArgumentException("displayToken must not be null"); 1934 } 1935 return nativeGetDisplayedContentSample(displayToken, maxFrames, timestamp); 1936 } 1937 1938 1939 /** 1940 * Contains information about desired display configuration. 1941 * 1942 * @hide 1943 */ 1944 public static final class DesiredDisplayModeSpecs { 1945 public int defaultMode; 1946 /** 1947 * The primary refresh rate range represents display manager's general guidance on the 1948 * display configs surface flinger will consider when switching refresh rates. Unless 1949 * surface flinger has a specific reason to do otherwise, it will stay within this range. 1950 */ 1951 public float primaryRefreshRateMin; 1952 public float primaryRefreshRateMax; 1953 /** 1954 * The app request refresh rate range allows surface flinger to consider more display 1955 * configs when switching refresh rates. Although surface flinger will generally stay within 1956 * the primary range, specific considerations, such as layer frame rate settings specified 1957 * via the setFrameRate() api, may cause surface flinger to go outside the primary 1958 * range. Surface flinger never goes outside the app request range. The app request range 1959 * will be greater than or equal to the primary refresh rate range, never smaller. 1960 */ 1961 public float appRequestRefreshRateMin; 1962 public float appRequestRefreshRateMax; 1963 1964 /** 1965 * If true this will allow switching between modes in different display configuration 1966 * groups. This way the user may see visual interruptions when the display mode changes. 1967 */ 1968 public boolean allowGroupSwitching; 1969 DesiredDisplayModeSpecs()1970 public DesiredDisplayModeSpecs() {} 1971 DesiredDisplayModeSpecs(DesiredDisplayModeSpecs other)1972 public DesiredDisplayModeSpecs(DesiredDisplayModeSpecs other) { 1973 copyFrom(other); 1974 } 1975 DesiredDisplayModeSpecs(int defaultMode, boolean allowGroupSwitching, float primaryRefreshRateMin, float primaryRefreshRateMax, float appRequestRefreshRateMin, float appRequestRefreshRateMax)1976 public DesiredDisplayModeSpecs(int defaultMode, boolean allowGroupSwitching, 1977 float primaryRefreshRateMin, float primaryRefreshRateMax, 1978 float appRequestRefreshRateMin, float appRequestRefreshRateMax) { 1979 this.defaultMode = defaultMode; 1980 this.allowGroupSwitching = allowGroupSwitching; 1981 this.primaryRefreshRateMin = primaryRefreshRateMin; 1982 this.primaryRefreshRateMax = primaryRefreshRateMax; 1983 this.appRequestRefreshRateMin = appRequestRefreshRateMin; 1984 this.appRequestRefreshRateMax = appRequestRefreshRateMax; 1985 } 1986 1987 @Override equals(@ullable Object o)1988 public boolean equals(@Nullable Object o) { 1989 return o instanceof DesiredDisplayModeSpecs && equals((DesiredDisplayModeSpecs) o); 1990 } 1991 1992 /** 1993 * Tests for equality. 1994 */ equals(DesiredDisplayModeSpecs other)1995 public boolean equals(DesiredDisplayModeSpecs other) { 1996 return other != null && defaultMode == other.defaultMode 1997 && primaryRefreshRateMin == other.primaryRefreshRateMin 1998 && primaryRefreshRateMax == other.primaryRefreshRateMax 1999 && appRequestRefreshRateMin == other.appRequestRefreshRateMin 2000 && appRequestRefreshRateMax == other.appRequestRefreshRateMax; 2001 } 2002 2003 @Override hashCode()2004 public int hashCode() { 2005 return 0; // don't care 2006 } 2007 2008 /** 2009 * Copies the supplied object's values to this object. 2010 */ copyFrom(DesiredDisplayModeSpecs other)2011 public void copyFrom(DesiredDisplayModeSpecs other) { 2012 defaultMode = other.defaultMode; 2013 primaryRefreshRateMin = other.primaryRefreshRateMin; 2014 primaryRefreshRateMax = other.primaryRefreshRateMax; 2015 appRequestRefreshRateMin = other.appRequestRefreshRateMin; 2016 appRequestRefreshRateMax = other.appRequestRefreshRateMax; 2017 } 2018 2019 @Override toString()2020 public String toString() { 2021 return String.format("defaultConfig=%d primaryRefreshRateRange=[%.0f %.0f]" 2022 + " appRequestRefreshRateRange=[%.0f %.0f]", 2023 defaultMode, primaryRefreshRateMin, primaryRefreshRateMax, 2024 appRequestRefreshRateMin, appRequestRefreshRateMax); 2025 } 2026 } 2027 2028 /** 2029 * @hide 2030 */ setDesiredDisplayModeSpecs(IBinder displayToken, DesiredDisplayModeSpecs desiredDisplayModeSpecs)2031 public static boolean setDesiredDisplayModeSpecs(IBinder displayToken, 2032 DesiredDisplayModeSpecs desiredDisplayModeSpecs) { 2033 if (displayToken == null) { 2034 throw new IllegalArgumentException("displayToken must not be null"); 2035 } 2036 if (desiredDisplayModeSpecs == null) { 2037 throw new IllegalArgumentException("desiredDisplayModeSpecs must not be null"); 2038 } 2039 if (desiredDisplayModeSpecs.defaultMode < 0) { 2040 throw new IllegalArgumentException("defaultMode must be non-negative"); 2041 } 2042 2043 return nativeSetDesiredDisplayModeSpecs(displayToken, desiredDisplayModeSpecs); 2044 } 2045 2046 /** 2047 * @hide 2048 */ getDesiredDisplayModeSpecs( IBinder displayToken)2049 public static DesiredDisplayModeSpecs getDesiredDisplayModeSpecs( 2050 IBinder displayToken) { 2051 if (displayToken == null) { 2052 throw new IllegalArgumentException("displayToken must not be null"); 2053 } 2054 2055 return nativeGetDesiredDisplayModeSpecs(displayToken); 2056 } 2057 2058 /** 2059 * Color coordinates in CIE1931 XYZ color space 2060 * 2061 * @hide 2062 */ 2063 public static final class CieXyz { 2064 /** 2065 * @hide 2066 */ 2067 public float X; 2068 2069 /** 2070 * @hide 2071 */ 2072 public float Y; 2073 2074 /** 2075 * @hide 2076 */ 2077 public float Z; 2078 } 2079 2080 /** 2081 * Contains a display's color primaries 2082 * 2083 * @hide 2084 */ 2085 public static final class DisplayPrimaries { 2086 /** 2087 * @hide 2088 */ 2089 public CieXyz red; 2090 2091 /** 2092 * @hide 2093 */ 2094 public CieXyz green; 2095 2096 /** 2097 * @hide 2098 */ 2099 public CieXyz blue; 2100 2101 /** 2102 * @hide 2103 */ 2104 public CieXyz white; 2105 2106 /** 2107 * @hide 2108 */ DisplayPrimaries()2109 public DisplayPrimaries() { 2110 } 2111 } 2112 2113 /** 2114 * @hide 2115 */ getDisplayNativePrimaries( IBinder displayToken)2116 public static DisplayPrimaries getDisplayNativePrimaries( 2117 IBinder displayToken) { 2118 if (displayToken == null) { 2119 throw new IllegalArgumentException("displayToken must not be null"); 2120 } 2121 2122 return nativeGetDisplayNativePrimaries(displayToken); 2123 } 2124 2125 /** 2126 * @hide 2127 */ setActiveColorMode(IBinder displayToken, int colorMode)2128 public static boolean setActiveColorMode(IBinder displayToken, int colorMode) { 2129 if (displayToken == null) { 2130 throw new IllegalArgumentException("displayToken must not be null"); 2131 } 2132 return nativeSetActiveColorMode(displayToken, colorMode); 2133 } 2134 2135 /** 2136 * Returns an array of color spaces with 2 elements. The first color space is the 2137 * default color space and second one is wide color gamut color space. 2138 * @hide 2139 */ getCompositionColorSpaces()2140 public static ColorSpace[] getCompositionColorSpaces() { 2141 int[] dataspaces = nativeGetCompositionDataspaces(); 2142 ColorSpace srgb = ColorSpace.get(ColorSpace.Named.SRGB); 2143 ColorSpace[] colorSpaces = { srgb, srgb }; 2144 if (dataspaces.length == 2) { 2145 for (int i = 0; i < 2; ++i) { 2146 switch(dataspaces[i]) { 2147 case INTERNAL_DATASPACE_DISPLAY_P3: 2148 colorSpaces[i] = ColorSpace.get(ColorSpace.Named.DISPLAY_P3); 2149 break; 2150 case INTERNAL_DATASPACE_SCRGB: 2151 colorSpaces[i] = ColorSpace.get(ColorSpace.Named.EXTENDED_SRGB); 2152 break; 2153 case INTERNAL_DATASPACE_SRGB: 2154 // Other dataspace is not recognized, use SRGB color space instead, 2155 // the default value of the array is already SRGB, thus do nothing. 2156 default: 2157 break; 2158 } 2159 } 2160 } 2161 return colorSpaces; 2162 } 2163 2164 /** 2165 * @hide 2166 */ setAutoLowLatencyMode(IBinder displayToken, boolean on)2167 public static void setAutoLowLatencyMode(IBinder displayToken, boolean on) { 2168 if (displayToken == null) { 2169 throw new IllegalArgumentException("displayToken must not be null"); 2170 } 2171 2172 nativeSetAutoLowLatencyMode(displayToken, on); 2173 } 2174 2175 /** 2176 * @hide 2177 */ setGameContentType(IBinder displayToken, boolean on)2178 public static void setGameContentType(IBinder displayToken, boolean on) { 2179 if (displayToken == null) { 2180 throw new IllegalArgumentException("displayToken must not be null"); 2181 } 2182 2183 nativeSetGameContentType(displayToken, on); 2184 } 2185 2186 /** 2187 * @hide 2188 */ 2189 @UnsupportedAppUsage setDisplayProjection(IBinder displayToken, int orientation, Rect layerStackRect, Rect displayRect)2190 public static void setDisplayProjection(IBinder displayToken, 2191 int orientation, Rect layerStackRect, Rect displayRect) { 2192 synchronized (SurfaceControl.class) { 2193 sGlobalTransaction.setDisplayProjection(displayToken, orientation, 2194 layerStackRect, displayRect); 2195 } 2196 } 2197 2198 /** 2199 * @hide 2200 */ 2201 @UnsupportedAppUsage setDisplayLayerStack(IBinder displayToken, int layerStack)2202 public static void setDisplayLayerStack(IBinder displayToken, int layerStack) { 2203 synchronized (SurfaceControl.class) { 2204 sGlobalTransaction.setDisplayLayerStack(displayToken, layerStack); 2205 } 2206 } 2207 2208 /** 2209 * @hide 2210 */ 2211 @UnsupportedAppUsage setDisplaySurface(IBinder displayToken, Surface surface)2212 public static void setDisplaySurface(IBinder displayToken, Surface surface) { 2213 synchronized (SurfaceControl.class) { 2214 sGlobalTransaction.setDisplaySurface(displayToken, surface); 2215 } 2216 } 2217 2218 /** 2219 * @hide 2220 */ setDisplaySize(IBinder displayToken, int width, int height)2221 public static void setDisplaySize(IBinder displayToken, int width, int height) { 2222 synchronized (SurfaceControl.class) { 2223 sGlobalTransaction.setDisplaySize(displayToken, width, height); 2224 } 2225 } 2226 2227 /** 2228 * Overrides HDR modes for a display device. 2229 * 2230 * If the caller does not have ACCESS_SURFACE_FLINGER permission, this will throw a Security 2231 * Exception. 2232 * @hide 2233 */ 2234 @TestApi overrideHdrTypes(@onNull IBinder displayToken, @NonNull int[] modes)2235 public static void overrideHdrTypes(@NonNull IBinder displayToken, @NonNull int[] modes) { 2236 nativeOverrideHdrTypes(displayToken, modes); 2237 } 2238 2239 /** 2240 * @hide 2241 */ 2242 @UnsupportedAppUsage createDisplay(String name, boolean secure)2243 public static IBinder createDisplay(String name, boolean secure) { 2244 if (name == null) { 2245 throw new IllegalArgumentException("name must not be null"); 2246 } 2247 return nativeCreateDisplay(name, secure); 2248 } 2249 2250 /** 2251 * @hide 2252 */ 2253 @UnsupportedAppUsage destroyDisplay(IBinder displayToken)2254 public static void destroyDisplay(IBinder displayToken) { 2255 if (displayToken == null) { 2256 throw new IllegalArgumentException("displayToken must not be null"); 2257 } 2258 nativeDestroyDisplay(displayToken); 2259 } 2260 2261 /** 2262 * @hide 2263 */ getPhysicalDisplayIds()2264 public static long[] getPhysicalDisplayIds() { 2265 return nativeGetPhysicalDisplayIds(); 2266 } 2267 2268 /** 2269 * @hide 2270 */ getPhysicalDisplayToken(long physicalDisplayId)2271 public static IBinder getPhysicalDisplayToken(long physicalDisplayId) { 2272 return nativeGetPhysicalDisplayToken(physicalDisplayId); 2273 } 2274 2275 /** 2276 * TODO(b/116025192): Remove this stopgap once framework is display-agnostic. 2277 * 2278 * @hide 2279 */ 2280 @TestApi 2281 @NonNull getInternalDisplayToken()2282 public static IBinder getInternalDisplayToken() { 2283 final long[] physicalDisplayIds = getPhysicalDisplayIds(); 2284 if (physicalDisplayIds.length == 0) { 2285 return null; 2286 } 2287 return getPhysicalDisplayToken(physicalDisplayIds[0]); 2288 } 2289 2290 /** 2291 * @param captureArgs Arguments about how to take the screenshot 2292 * @param captureListener A listener to receive the screenshot callback 2293 * @hide 2294 */ captureDisplay(@onNull DisplayCaptureArgs captureArgs, @NonNull ScreenCaptureListener captureListener)2295 public static int captureDisplay(@NonNull DisplayCaptureArgs captureArgs, 2296 @NonNull ScreenCaptureListener captureListener) { 2297 return nativeCaptureDisplay(captureArgs, captureListener); 2298 } 2299 2300 /** 2301 * Captures all the surfaces in a display and returns a {@link ScreenshotHardwareBuffer} with 2302 * the content. 2303 * 2304 * @hide 2305 */ captureDisplay(DisplayCaptureArgs captureArgs)2306 public static ScreenshotHardwareBuffer captureDisplay(DisplayCaptureArgs captureArgs) { 2307 SyncScreenCaptureListener screenCaptureListener = new SyncScreenCaptureListener(); 2308 2309 int status = captureDisplay(captureArgs, screenCaptureListener); 2310 if (status != 0) { 2311 return null; 2312 } 2313 2314 return screenCaptureListener.waitForScreenshot(); 2315 } 2316 2317 /** 2318 * Captures a layer and its children and returns a {@link HardwareBuffer} with the content. 2319 * 2320 * @param layer The root layer to capture. 2321 * @param sourceCrop The portion of the root surface to capture; caller may pass in 'new 2322 * Rect()' or null if no cropping is desired. If the root layer does not 2323 * have a buffer or a crop set, then a non-empty source crop must be 2324 * specified. 2325 * @param frameScale The desired scale of the returned buffer; the raw 2326 * screen will be scaled up/down. 2327 * 2328 * @return Returns a HardwareBuffer that contains the layer capture. 2329 * @hide 2330 */ captureLayers(SurfaceControl layer, Rect sourceCrop, float frameScale)2331 public static ScreenshotHardwareBuffer captureLayers(SurfaceControl layer, Rect sourceCrop, 2332 float frameScale) { 2333 return captureLayers(layer, sourceCrop, frameScale, PixelFormat.RGBA_8888); 2334 } 2335 2336 /** 2337 * Captures a layer and its children and returns a {@link HardwareBuffer} with the content. 2338 * 2339 * @param layer The root layer to capture. 2340 * @param sourceCrop The portion of the root surface to capture; caller may pass in 'new 2341 * Rect()' or null if no cropping is desired. If the root layer does not 2342 * have a buffer or a crop set, then a non-empty source crop must be 2343 * specified. 2344 * @param frameScale The desired scale of the returned buffer; the raw 2345 * screen will be scaled up/down. 2346 * @param format The desired pixel format of the returned buffer. 2347 * 2348 * @return Returns a HardwareBuffer that contains the layer capture. 2349 * @hide 2350 */ captureLayers(SurfaceControl layer, Rect sourceCrop, float frameScale, int format)2351 public static ScreenshotHardwareBuffer captureLayers(SurfaceControl layer, Rect sourceCrop, 2352 float frameScale, int format) { 2353 LayerCaptureArgs captureArgs = new LayerCaptureArgs.Builder(layer) 2354 .setSourceCrop(sourceCrop) 2355 .setFrameScale(frameScale) 2356 .setPixelFormat(format) 2357 .build(); 2358 2359 return captureLayers(captureArgs); 2360 } 2361 2362 /** 2363 * @hide 2364 */ captureLayers(LayerCaptureArgs captureArgs)2365 public static ScreenshotHardwareBuffer captureLayers(LayerCaptureArgs captureArgs) { 2366 SyncScreenCaptureListener screenCaptureListener = new SyncScreenCaptureListener(); 2367 2368 int status = captureLayers(captureArgs, screenCaptureListener); 2369 if (status != 0) { 2370 return null; 2371 } 2372 2373 return screenCaptureListener.waitForScreenshot(); 2374 } 2375 2376 /** 2377 * Like {@link #captureLayers(SurfaceControl, Rect, float, int)} but with an array of layer 2378 * handles to exclude. 2379 * @hide 2380 */ captureLayersExcluding(SurfaceControl layer, Rect sourceCrop, float frameScale, int format, SurfaceControl[] exclude)2381 public static ScreenshotHardwareBuffer captureLayersExcluding(SurfaceControl layer, 2382 Rect sourceCrop, float frameScale, int format, SurfaceControl[] exclude) { 2383 LayerCaptureArgs captureArgs = new LayerCaptureArgs.Builder(layer) 2384 .setSourceCrop(sourceCrop) 2385 .setFrameScale(frameScale) 2386 .setPixelFormat(format) 2387 .setExcludeLayers(exclude) 2388 .build(); 2389 2390 return captureLayers(captureArgs); 2391 } 2392 2393 /** 2394 * @param captureArgs Arguments about how to take the screenshot 2395 * @param captureListener A listener to receive the screenshot callback 2396 * @hide 2397 */ captureLayers(@onNull LayerCaptureArgs captureArgs, @NonNull ScreenCaptureListener captureListener)2398 public static int captureLayers(@NonNull LayerCaptureArgs captureArgs, 2399 @NonNull ScreenCaptureListener captureListener) { 2400 return nativeCaptureLayers(captureArgs, captureListener); 2401 } 2402 2403 /** 2404 * Returns whether protected content is supported in GPU composition. 2405 * @hide 2406 */ getProtectedContentSupport()2407 public static boolean getProtectedContentSupport() { 2408 return nativeGetProtectedContentSupport(); 2409 } 2410 2411 /** 2412 * Returns whether brightness operations are supported on a display. 2413 * 2414 * @param displayToken 2415 * The token for the display. 2416 * 2417 * @return Whether brightness operations are supported on the display. 2418 * 2419 * @hide 2420 */ getDisplayBrightnessSupport(IBinder displayToken)2421 public static boolean getDisplayBrightnessSupport(IBinder displayToken) { 2422 return nativeGetDisplayBrightnessSupport(displayToken); 2423 } 2424 2425 /** 2426 * Sets the brightness of a display. 2427 * 2428 * @param displayToken 2429 * The token for the display whose brightness is set. 2430 * @param brightness 2431 * A number between 0.0f (minimum brightness) and 1.0f (maximum brightness), or -1.0f to 2432 * turn the backlight off. 2433 * 2434 * @return Whether the method succeeded or not. 2435 * 2436 * @throws IllegalArgumentException if: 2437 * - displayToken is null; 2438 * - brightness is NaN or greater than 1.0f. 2439 * 2440 * @hide 2441 */ setDisplayBrightness(IBinder displayToken, float brightness)2442 public static boolean setDisplayBrightness(IBinder displayToken, float brightness) { 2443 return setDisplayBrightness(displayToken, brightness, -1, brightness, -1); 2444 } 2445 2446 /** 2447 * Sets the brightness of a display. 2448 * 2449 * @param displayToken 2450 * The token for the display whose brightness is set. 2451 * @param sdrBrightness 2452 * A number between 0.0f (minimum brightness) and 1.0f (maximum brightness), or -1.0f to 2453 * turn the backlight off. Specifies the desired brightness of SDR content. 2454 * @param sdrBrightnessNits 2455 * The value of sdrBrightness converted to calibrated nits. -1 if this isn't available. 2456 * @param displayBrightness 2457 * A number between 0.0f (minimum brightness) and 1.0f (maximum brightness), or 2458 * -1.0f to turn the backlight off. Specifies the desired brightness of the display itself, 2459 * used directly for HDR content. 2460 * @param displayBrightnessNits 2461 * The value of displayBrightness converted to calibrated nits. -1 if this isn't 2462 * available. 2463 * 2464 * @return Whether the method succeeded or not. 2465 * 2466 * @throws IllegalArgumentException if: 2467 * - displayToken is null; 2468 * - brightness is NaN or greater than 1.0f. 2469 * 2470 * @hide 2471 */ setDisplayBrightness(IBinder displayToken, float sdrBrightness, float sdrBrightnessNits, float displayBrightness, float displayBrightnessNits)2472 public static boolean setDisplayBrightness(IBinder displayToken, float sdrBrightness, 2473 float sdrBrightnessNits, float displayBrightness, float displayBrightnessNits) { 2474 Objects.requireNonNull(displayToken); 2475 if (Float.isNaN(displayBrightness) || displayBrightness > 1.0f 2476 || (displayBrightness < 0.0f && displayBrightness != -1.0f)) { 2477 throw new IllegalArgumentException("displayBrightness must be a number between 0.0f " 2478 + " and 1.0f, or -1 to turn the backlight off: " + displayBrightness); 2479 } 2480 if (Float.isNaN(sdrBrightness) || sdrBrightness > 1.0f 2481 || (sdrBrightness < 0.0f && sdrBrightness != -1.0f)) { 2482 throw new IllegalArgumentException("sdrBrightness must be a number between 0.0f " 2483 + "and 1.0f, or -1 to turn the backlight off: " + sdrBrightness); 2484 } 2485 return nativeSetDisplayBrightness(displayToken, sdrBrightness, sdrBrightnessNits, 2486 displayBrightness, displayBrightnessNits); 2487 } 2488 2489 /** 2490 * Creates a mirrored hierarchy for the mirrorOf {@link SurfaceControl} 2491 * 2492 * Real Hierarchy Mirror 2493 * SC (value that's returned) 2494 * | 2495 * A A' 2496 * | | 2497 * B B' 2498 * 2499 * @param mirrorOf The root of the hierarchy that should be mirrored. 2500 * @return A SurfaceControl that's the parent of the root of the mirrored hierarchy. 2501 * 2502 * @hide 2503 */ mirrorSurface(SurfaceControl mirrorOf)2504 public static SurfaceControl mirrorSurface(SurfaceControl mirrorOf) { 2505 long nativeObj = nativeMirrorSurface(mirrorOf.mNativeObject); 2506 SurfaceControl sc = new SurfaceControl(); 2507 sc.assignNativeObject(nativeObj, "mirrorSurface"); 2508 return sc; 2509 } 2510 validateColorArg(@ize4) float[] color)2511 private static void validateColorArg(@Size(4) float[] color) { 2512 final String msg = "Color must be specified as a float array with" 2513 + " four values to represent r, g, b, a in range [0..1]"; 2514 if (color.length != 4) { 2515 throw new IllegalArgumentException(msg); 2516 } 2517 for (float c:color) { 2518 if ((c < 0.f) || (c > 1.f)) { 2519 throw new IllegalArgumentException(msg); 2520 } 2521 } 2522 } 2523 2524 /** 2525 * Sets the global configuration for all the shadows drawn by SurfaceFlinger. Shadow follows 2526 * material design guidelines. 2527 * 2528 * @param ambientColor Color applied to the ambient shadow. The alpha is premultiplied. A 2529 * float array with four values to represent r, g, b, a in range [0..1] 2530 * @param spotColor Color applied to the spot shadow. The alpha is premultiplied. The position 2531 * of the spot shadow depends on the light position. A float array with 2532 * four values to represent r, g, b, a in range [0..1] 2533 * @param lightPosY Y axis position of the light used to cast the spot shadow in pixels. 2534 * @param lightPosZ Z axis position of the light used to cast the spot shadow in pixels. The X 2535 * axis position is set to the display width / 2. 2536 * @param lightRadius Radius of the light casting the shadow in pixels. 2537 *[ 2538 * @hide 2539 */ setGlobalShadowSettings(@ize4) float[] ambientColor, @Size(4) float[] spotColor, float lightPosY, float lightPosZ, float lightRadius)2540 public static void setGlobalShadowSettings(@Size(4) float[] ambientColor, 2541 @Size(4) float[] spotColor, float lightPosY, float lightPosZ, float lightRadius) { 2542 validateColorArg(ambientColor); 2543 validateColorArg(spotColor); 2544 nativeSetGlobalShadowSettings(ambientColor, spotColor, lightPosY, lightPosZ, lightRadius); 2545 } 2546 2547 /** 2548 * Adds a callback to be informed about SF's jank classification for a specific surface. 2549 * @hide 2550 */ addJankDataListener(OnJankDataListener listener, SurfaceControl surface)2551 public static void addJankDataListener(OnJankDataListener listener, SurfaceControl surface) { 2552 nativeAddJankDataListener(listener.mNativePtr.get(), surface.mNativeObject); 2553 } 2554 2555 /** 2556 * Removes a jank callback previously added with {@link #addJankDataListener} 2557 * @hide 2558 */ removeJankDataListener(OnJankDataListener listener)2559 public static void removeJankDataListener(OnJankDataListener listener) { 2560 nativeRemoveJankDataListener(listener.mNativePtr.get()); 2561 } 2562 2563 /** 2564 * Return GPU Context priority that is set in SurfaceFlinger's Render Engine. 2565 * @hide 2566 */ getGPUContextPriority()2567 public static int getGPUContextPriority() { 2568 return nativeGetGPUContextPriority(); 2569 } 2570 2571 /** 2572 * An atomic set of changes to a set of SurfaceControl. 2573 */ 2574 public static class Transaction implements Closeable, Parcelable { 2575 /** 2576 * @hide 2577 */ 2578 public static final NativeAllocationRegistry sRegistry = new NativeAllocationRegistry( 2579 Transaction.class.getClassLoader(), 2580 nativeGetNativeTransactionFinalizer(), 512); 2581 /** 2582 * @hide 2583 */ 2584 public long mNativeObject; 2585 2586 private final ArrayMap<SurfaceControl, Point> mResizedSurfaces = new ArrayMap<>(); 2587 private final ArrayMap<SurfaceControl, SurfaceControl> mReparentedSurfaces = 2588 new ArrayMap<>(); 2589 2590 Runnable mFreeNativeResources; 2591 private static final float[] INVALID_COLOR = {-1, -1, -1}; 2592 2593 /** 2594 * @hide 2595 */ checkPreconditions(SurfaceControl sc)2596 protected void checkPreconditions(SurfaceControl sc) { 2597 sc.checkNotReleased(); 2598 } 2599 2600 /** 2601 * Open a new transaction object. The transaction may be filed with commands to 2602 * manipulate {@link SurfaceControl} instances, and then applied atomically with 2603 * {@link #apply}. Eventually the user should invoke {@link #close}, when the object 2604 * is no longer required. Note however that re-using a transaction after a call to apply 2605 * is allowed as a convenience. 2606 */ Transaction()2607 public Transaction() { 2608 mNativeObject = nativeCreateTransaction(); 2609 mFreeNativeResources 2610 = sRegistry.registerNativeAllocation(this, mNativeObject); 2611 } 2612 Transaction(Parcel in)2613 private Transaction(Parcel in) { 2614 readFromParcel(in); 2615 } 2616 2617 /** 2618 * Apply the transaction, clearing it's state, and making it usable 2619 * as a new transaction. 2620 */ apply()2621 public void apply() { 2622 apply(false); 2623 } 2624 2625 /** 2626 * Clear the transaction object, without applying it. 2627 * 2628 * @hide 2629 */ clear()2630 public void clear() { 2631 mResizedSurfaces.clear(); 2632 mReparentedSurfaces.clear(); 2633 if (mNativeObject != 0) { 2634 nativeClearTransaction(mNativeObject); 2635 } 2636 } 2637 2638 /** 2639 * Release the native transaction object, without applying it. 2640 */ 2641 @Override close()2642 public void close() { 2643 mResizedSurfaces.clear(); 2644 mReparentedSurfaces.clear(); 2645 mFreeNativeResources.run(); 2646 mNativeObject = 0; 2647 } 2648 2649 /** 2650 * Jankier version of apply. Avoid use (b/28068298). 2651 * @hide 2652 */ apply(boolean sync)2653 public void apply(boolean sync) { 2654 applyResizedSurfaces(); 2655 notifyReparentedSurfaces(); 2656 nativeApplyTransaction(mNativeObject, sync); 2657 } 2658 2659 /** 2660 * @hide 2661 */ applyResizedSurfaces()2662 protected void applyResizedSurfaces() { 2663 for (int i = mResizedSurfaces.size() - 1; i >= 0; i--) { 2664 final Point size = mResizedSurfaces.valueAt(i); 2665 final SurfaceControl surfaceControl = mResizedSurfaces.keyAt(i); 2666 synchronized (surfaceControl.mLock) { 2667 surfaceControl.resize(size.x, size.y); 2668 } 2669 } 2670 mResizedSurfaces.clear(); 2671 } 2672 2673 /** 2674 * @hide 2675 */ notifyReparentedSurfaces()2676 protected void notifyReparentedSurfaces() { 2677 final int reparentCount = mReparentedSurfaces.size(); 2678 for (int i = reparentCount - 1; i >= 0; i--) { 2679 final SurfaceControl child = mReparentedSurfaces.keyAt(i); 2680 synchronized (child.mLock) { 2681 final int listenerCount = (child.mReparentListeners != null) 2682 ? child.mReparentListeners.size() : 0; 2683 for (int j = 0; j < listenerCount; j++) { 2684 final OnReparentListener listener = child.mReparentListeners.get(j); 2685 listener.onReparent(this, mReparentedSurfaces.valueAt(i)); 2686 } 2687 mReparentedSurfaces.removeAt(i); 2688 } 2689 } 2690 } 2691 2692 /** 2693 * Toggle the visibility of a given Layer and it's sub-tree. 2694 * 2695 * @param sc The SurfaceControl for which to set the visibility 2696 * @param visible The new visibility 2697 * @return This transaction object. 2698 */ 2699 @NonNull setVisibility(@onNull SurfaceControl sc, boolean visible)2700 public Transaction setVisibility(@NonNull SurfaceControl sc, boolean visible) { 2701 checkPreconditions(sc); 2702 if (visible) { 2703 return show(sc); 2704 } else { 2705 return hide(sc); 2706 } 2707 } 2708 2709 /** 2710 * This information is passed to SurfaceFlinger to decide which window should have a 2711 * priority when deciding about the refresh rate of the display. All windows have the 2712 * lowest priority by default. 2713 * @hide 2714 */ 2715 @NonNull setFrameRateSelectionPriority(@onNull SurfaceControl sc, int priority)2716 public Transaction setFrameRateSelectionPriority(@NonNull SurfaceControl sc, int priority) { 2717 sc.checkNotReleased(); 2718 nativeSetFrameRateSelectionPriority(mNativeObject, sc.mNativeObject, priority); 2719 return this; 2720 } 2721 2722 /** 2723 * Request that a given surface and it's sub-tree be shown. 2724 * 2725 * @param sc The surface to show. 2726 * @return This transaction. 2727 * @hide 2728 */ 2729 @UnsupportedAppUsage show(SurfaceControl sc)2730 public Transaction show(SurfaceControl sc) { 2731 checkPreconditions(sc); 2732 nativeSetFlags(mNativeObject, sc.mNativeObject, 0, SURFACE_HIDDEN); 2733 return this; 2734 } 2735 2736 /** 2737 * Request that a given surface and it's sub-tree be hidden. 2738 * 2739 * @param sc The surface to hidden. 2740 * @return This transaction. 2741 * @hide 2742 */ 2743 @UnsupportedAppUsage hide(SurfaceControl sc)2744 public Transaction hide(SurfaceControl sc) { 2745 checkPreconditions(sc); 2746 nativeSetFlags(mNativeObject, sc.mNativeObject, SURFACE_HIDDEN, SURFACE_HIDDEN); 2747 return this; 2748 } 2749 2750 /** 2751 * @hide 2752 */ 2753 @UnsupportedAppUsage setPosition(SurfaceControl sc, float x, float y)2754 public Transaction setPosition(SurfaceControl sc, float x, float y) { 2755 checkPreconditions(sc); 2756 nativeSetPosition(mNativeObject, sc.mNativeObject, x, y); 2757 return this; 2758 } 2759 2760 /** 2761 * Set the default buffer size for the SurfaceControl, if there is a 2762 * {@link Surface} associated with the control, then 2763 * this will be the default size for buffers dequeued from it. 2764 * @param sc The surface to set the buffer size for. 2765 * @param w The default width 2766 * @param h The default height 2767 * @return This Transaction 2768 */ 2769 @NonNull setBufferSize(@onNull SurfaceControl sc, @IntRange(from = 0) int w, @IntRange(from = 0) int h)2770 public Transaction setBufferSize(@NonNull SurfaceControl sc, 2771 @IntRange(from = 0) int w, @IntRange(from = 0) int h) { 2772 checkPreconditions(sc); 2773 mResizedSurfaces.put(sc, new Point(w, h)); 2774 nativeSetSize(mNativeObject, sc.mNativeObject, w, h); 2775 return this; 2776 } 2777 2778 /** 2779 * Provide the graphic producer a transform hint if the layer and its children are 2780 * in an orientation different from the display's orientation. The caller is responsible 2781 * for clearing this transform hint if the layer is no longer in a fixed orientation. 2782 * 2783 * The transform hint is used to prevent allocating a buffer of different size when a 2784 * layer is rotated. The producer can choose to consume the hint and allocate the buffer 2785 * with the same size. 2786 * 2787 * @return This Transaction. 2788 * @hide 2789 */ 2790 @NonNull setFixedTransformHint(@onNull SurfaceControl sc, @Surface.Rotation int transformHint)2791 public Transaction setFixedTransformHint(@NonNull SurfaceControl sc, 2792 @Surface.Rotation int transformHint) { 2793 checkPreconditions(sc); 2794 nativeSetFixedTransformHint(mNativeObject, sc.mNativeObject, transformHint); 2795 return this; 2796 } 2797 2798 /** 2799 * Clearing any transform hint if set on this layer. 2800 * 2801 * @return This Transaction. 2802 * @hide 2803 */ 2804 @NonNull unsetFixedTransformHint(@onNull SurfaceControl sc)2805 public Transaction unsetFixedTransformHint(@NonNull SurfaceControl sc) { 2806 checkPreconditions(sc); 2807 nativeSetFixedTransformHint(mNativeObject, sc.mNativeObject, -1/* INVALID_ROTATION */); 2808 return this; 2809 } 2810 2811 /** 2812 * Set the Z-order for a given SurfaceControl, relative to it's siblings. 2813 * If two siblings share the same Z order the ordering is undefined. Surfaces 2814 * with a negative Z will be placed below the parent surface. 2815 * 2816 * @param sc The SurfaceControl to set the Z order on 2817 * @param z The Z-order 2818 * @return This Transaction. 2819 */ 2820 @NonNull setLayer(@onNull SurfaceControl sc, @IntRange(from = Integer.MIN_VALUE, to = Integer.MAX_VALUE) int z)2821 public Transaction setLayer(@NonNull SurfaceControl sc, 2822 @IntRange(from = Integer.MIN_VALUE, to = Integer.MAX_VALUE) int z) { 2823 checkPreconditions(sc); 2824 nativeSetLayer(mNativeObject, sc.mNativeObject, z); 2825 return this; 2826 } 2827 2828 /** 2829 * @hide 2830 */ setRelativeLayer(SurfaceControl sc, SurfaceControl relativeTo, int z)2831 public Transaction setRelativeLayer(SurfaceControl sc, SurfaceControl relativeTo, int z) { 2832 checkPreconditions(sc); 2833 nativeSetRelativeLayer(mNativeObject, sc.mNativeObject, relativeTo.mNativeObject, z); 2834 return this; 2835 } 2836 2837 /** 2838 * @hide 2839 */ setTransparentRegionHint(SurfaceControl sc, Region transparentRegion)2840 public Transaction setTransparentRegionHint(SurfaceControl sc, Region transparentRegion) { 2841 checkPreconditions(sc); 2842 nativeSetTransparentRegionHint(mNativeObject, 2843 sc.mNativeObject, transparentRegion); 2844 return this; 2845 } 2846 2847 /** 2848 * Set the alpha for a given surface. If the alpha is non-zero the SurfaceControl 2849 * will be blended with the Surfaces under it according to the specified ratio. 2850 * 2851 * @param sc The given SurfaceControl. 2852 * @param alpha The alpha to set. 2853 */ 2854 @NonNull setAlpha(@onNull SurfaceControl sc, @FloatRange(from = 0.0, to = 1.0) float alpha)2855 public Transaction setAlpha(@NonNull SurfaceControl sc, 2856 @FloatRange(from = 0.0, to = 1.0) float alpha) { 2857 checkPreconditions(sc); 2858 nativeSetAlpha(mNativeObject, sc.mNativeObject, alpha); 2859 return this; 2860 } 2861 2862 /** 2863 * @hide 2864 */ setInputWindowInfo(SurfaceControl sc, InputWindowHandle handle)2865 public Transaction setInputWindowInfo(SurfaceControl sc, InputWindowHandle handle) { 2866 checkPreconditions(sc); 2867 nativeSetInputWindowInfo(mNativeObject, sc.mNativeObject, handle); 2868 return this; 2869 } 2870 2871 /** 2872 * Waits until any changes to input windows have been sent from SurfaceFlinger to 2873 * InputFlinger before returning. 2874 * 2875 * @hide 2876 */ syncInputWindows()2877 public Transaction syncInputWindows() { 2878 nativeSyncInputWindows(mNativeObject); 2879 return this; 2880 } 2881 2882 /** 2883 * Specify how the buffer associated with this Surface is mapped in to the 2884 * parent coordinate space. The source frame will be scaled to fit the destination 2885 * frame, after being rotated according to the orientation parameter. 2886 * 2887 * @param sc The SurfaceControl to specify the geometry of 2888 * @param sourceCrop The source rectangle in buffer space. Or null for the entire buffer. 2889 * @param destFrame The destination rectangle in parent space. Or null for the source frame. 2890 * @param orientation The buffer rotation 2891 * @return This transaction object. 2892 */ 2893 @NonNull setGeometry(@onNull SurfaceControl sc, @Nullable Rect sourceCrop, @Nullable Rect destFrame, @Surface.Rotation int orientation)2894 public Transaction setGeometry(@NonNull SurfaceControl sc, @Nullable Rect sourceCrop, 2895 @Nullable Rect destFrame, @Surface.Rotation int orientation) { 2896 checkPreconditions(sc); 2897 nativeSetGeometry(mNativeObject, sc.mNativeObject, sourceCrop, destFrame, orientation); 2898 return this; 2899 } 2900 2901 /** 2902 * @hide 2903 */ 2904 @UnsupportedAppUsage setMatrix(SurfaceControl sc, float dsdx, float dtdx, float dtdy, float dsdy)2905 public Transaction setMatrix(SurfaceControl sc, 2906 float dsdx, float dtdx, float dtdy, float dsdy) { 2907 checkPreconditions(sc); 2908 nativeSetMatrix(mNativeObject, sc.mNativeObject, 2909 dsdx, dtdx, dtdy, dsdy); 2910 return this; 2911 } 2912 2913 /** 2914 * Sets the transform and position of a {@link SurfaceControl} from a 3x3 transformation 2915 * matrix. 2916 * 2917 * @param sc SurfaceControl to set matrix of 2918 * @param matrix The matrix to apply. 2919 * @param float9 An array of 9 floats to be used to extract the values from the matrix. 2920 * @hide 2921 */ 2922 @UnsupportedAppUsage setMatrix(SurfaceControl sc, Matrix matrix, float[] float9)2923 public Transaction setMatrix(SurfaceControl sc, Matrix matrix, float[] float9) { 2924 matrix.getValues(float9); 2925 setMatrix(sc, float9[MSCALE_X], float9[MSKEW_Y], 2926 float9[MSKEW_X], float9[MSCALE_Y]); 2927 setPosition(sc, float9[MTRANS_X], float9[MTRANS_Y]); 2928 return this; 2929 } 2930 2931 /** 2932 * Sets the color transform for the Surface. 2933 * 2934 * @param sc SurfaceControl to set color transform of 2935 * @param matrix A float array with 9 values represents a 3x3 transform matrix 2936 * @param translation A float array with 3 values represents a translation vector 2937 * @hide 2938 */ setColorTransform(SurfaceControl sc, @Size(9) float[] matrix, @Size(3) float[] translation)2939 public Transaction setColorTransform(SurfaceControl sc, @Size(9) float[] matrix, 2940 @Size(3) float[] translation) { 2941 checkPreconditions(sc); 2942 nativeSetColorTransform(mNativeObject, sc.mNativeObject, matrix, translation); 2943 return this; 2944 } 2945 2946 /** 2947 * Sets the Surface to be color space agnostic. If a surface is color space agnostic, 2948 * the color can be interpreted in any color space. 2949 * @param agnostic A boolean to indicate whether the surface is color space agnostic 2950 * @hide 2951 */ setColorSpaceAgnostic(SurfaceControl sc, boolean agnostic)2952 public Transaction setColorSpaceAgnostic(SurfaceControl sc, boolean agnostic) { 2953 checkPreconditions(sc); 2954 nativeSetColorSpaceAgnostic(mNativeObject, sc.mNativeObject, agnostic); 2955 return this; 2956 } 2957 2958 /** 2959 * Bounds the surface and its children to the bounds specified. Size of the surface will be 2960 * ignored and only the crop and buffer size will be used to determine the bounds of the 2961 * surface. If no crop is specified and the surface has no buffer, the surface bounds is 2962 * only constrained by the size of its parent bounds. 2963 * 2964 * @param sc SurfaceControl to set crop of. 2965 * @param crop Bounds of the crop to apply. 2966 * @hide 2967 */ 2968 @UnsupportedAppUsage setWindowCrop(SurfaceControl sc, Rect crop)2969 public Transaction setWindowCrop(SurfaceControl sc, Rect crop) { 2970 checkPreconditions(sc); 2971 if (crop != null) { 2972 nativeSetWindowCrop(mNativeObject, sc.mNativeObject, 2973 crop.left, crop.top, crop.right, crop.bottom); 2974 } else { 2975 nativeSetWindowCrop(mNativeObject, sc.mNativeObject, 0, 0, 0, 0); 2976 } 2977 2978 return this; 2979 } 2980 2981 /** 2982 * Same as {@link Transaction#setWindowCrop(SurfaceControl, Rect)} but sets the crop rect 2983 * top left at 0, 0. 2984 * 2985 * @param sc SurfaceControl to set crop of. 2986 * @param width width of crop rect 2987 * @param height height of crop rect 2988 * @hide 2989 */ setWindowCrop(SurfaceControl sc, int width, int height)2990 public Transaction setWindowCrop(SurfaceControl sc, int width, int height) { 2991 checkPreconditions(sc); 2992 nativeSetWindowCrop(mNativeObject, sc.mNativeObject, 0, 0, width, height); 2993 return this; 2994 } 2995 2996 /** 2997 * Sets the corner radius of a {@link SurfaceControl}. 2998 * @param sc SurfaceControl 2999 * @param cornerRadius Corner radius in pixels. 3000 * @return Itself. 3001 * @hide 3002 */ 3003 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) setCornerRadius(SurfaceControl sc, float cornerRadius)3004 public Transaction setCornerRadius(SurfaceControl sc, float cornerRadius) { 3005 checkPreconditions(sc); 3006 nativeSetCornerRadius(mNativeObject, sc.mNativeObject, cornerRadius); 3007 3008 return this; 3009 } 3010 3011 /** 3012 * Sets the background blur radius of the {@link SurfaceControl}. 3013 * 3014 * @param sc SurfaceControl. 3015 * @param radius Blur radius in pixels. 3016 * @return itself. 3017 * @hide 3018 */ setBackgroundBlurRadius(SurfaceControl sc, int radius)3019 public Transaction setBackgroundBlurRadius(SurfaceControl sc, int radius) { 3020 checkPreconditions(sc); 3021 nativeSetBackgroundBlurRadius(mNativeObject, sc.mNativeObject, radius); 3022 return this; 3023 } 3024 3025 /** 3026 * Specify what regions should be blurred on the {@link SurfaceControl}. 3027 * 3028 * @param sc SurfaceControl. 3029 * @param regions List of regions that will have blurs. 3030 * @return itself. 3031 * @see BlurRegion#toFloatArray() 3032 * @hide 3033 */ setBlurRegions(SurfaceControl sc, float[][] regions)3034 public Transaction setBlurRegions(SurfaceControl sc, float[][] regions) { 3035 checkPreconditions(sc); 3036 nativeSetBlurRegions(mNativeObject, sc.mNativeObject, regions, regions.length); 3037 return this; 3038 } 3039 3040 /** 3041 * @hide 3042 */ setStretchEffect(SurfaceControl sc, float width, float height, float vecX, float vecY, float maxStretchAmountX, float maxStretchAmountY, float childRelativeLeft, float childRelativeTop, float childRelativeRight, float childRelativeBottom)3043 public Transaction setStretchEffect(SurfaceControl sc, float width, float height, 3044 float vecX, float vecY, float maxStretchAmountX, 3045 float maxStretchAmountY, float childRelativeLeft, float childRelativeTop, float childRelativeRight, 3046 float childRelativeBottom) { 3047 checkPreconditions(sc); 3048 nativeSetStretchEffect(mNativeObject, sc.mNativeObject, width, height, 3049 vecX, vecY, maxStretchAmountX, maxStretchAmountY, childRelativeLeft, childRelativeTop, 3050 childRelativeRight, childRelativeBottom); 3051 return this; 3052 } 3053 3054 /** 3055 * @hide 3056 */ 3057 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.O) setLayerStack(SurfaceControl sc, int layerStack)3058 public Transaction setLayerStack(SurfaceControl sc, int layerStack) { 3059 checkPreconditions(sc); 3060 nativeSetLayerStack(mNativeObject, sc.mNativeObject, layerStack); 3061 return this; 3062 } 3063 3064 /** 3065 * Re-parents a given layer to a new parent. Children inherit transform (position, scaling) 3066 * crop, visibility, and Z-ordering from their parents, as if the children were pixels within the 3067 * parent Surface. 3068 * 3069 * @param sc The SurfaceControl to reparent 3070 * @param newParent The new parent for the given control. 3071 * @return This Transaction 3072 */ 3073 @NonNull reparent(@onNull SurfaceControl sc, @Nullable SurfaceControl newParent)3074 public Transaction reparent(@NonNull SurfaceControl sc, 3075 @Nullable SurfaceControl newParent) { 3076 checkPreconditions(sc); 3077 long otherObject = 0; 3078 if (newParent != null) { 3079 newParent.checkNotReleased(); 3080 otherObject = newParent.mNativeObject; 3081 } 3082 nativeReparent(mNativeObject, sc.mNativeObject, otherObject); 3083 mReparentedSurfaces.put(sc, newParent); 3084 return this; 3085 } 3086 3087 /** 3088 * Fills the surface with the specified color. 3089 * @param color A float array with three values to represent r, g, b in range [0..1]. An 3090 * invalid color will remove the color fill. 3091 * @hide 3092 */ 3093 @UnsupportedAppUsage setColor(SurfaceControl sc, @Size(3) float[] color)3094 public Transaction setColor(SurfaceControl sc, @Size(3) float[] color) { 3095 checkPreconditions(sc); 3096 nativeSetColor(mNativeObject, sc.mNativeObject, color); 3097 return this; 3098 } 3099 3100 /** 3101 * Removes color fill. 3102 * @hide 3103 */ unsetColor(SurfaceControl sc)3104 public Transaction unsetColor(SurfaceControl sc) { 3105 checkPreconditions(sc); 3106 nativeSetColor(mNativeObject, sc.mNativeObject, INVALID_COLOR); 3107 return this; 3108 } 3109 3110 /** 3111 * Sets the security of the surface. Setting the flag is equivalent to creating the 3112 * Surface with the {@link #SECURE} flag. 3113 * @hide 3114 */ setSecure(SurfaceControl sc, boolean isSecure)3115 public Transaction setSecure(SurfaceControl sc, boolean isSecure) { 3116 checkPreconditions(sc); 3117 if (isSecure) { 3118 nativeSetFlags(mNativeObject, sc.mNativeObject, SECURE, SECURE); 3119 } else { 3120 nativeSetFlags(mNativeObject, sc.mNativeObject, 0, SECURE); 3121 } 3122 return this; 3123 } 3124 3125 /** 3126 * Sets the opacity of the surface. Setting the flag is equivalent to creating the 3127 * Surface with the {@link #OPAQUE} flag. 3128 * @hide 3129 */ setOpaque(SurfaceControl sc, boolean isOpaque)3130 public Transaction setOpaque(SurfaceControl sc, boolean isOpaque) { 3131 checkPreconditions(sc); 3132 if (isOpaque) { 3133 nativeSetFlags(mNativeObject, sc.mNativeObject, SURFACE_OPAQUE, SURFACE_OPAQUE); 3134 } else { 3135 nativeSetFlags(mNativeObject, sc.mNativeObject, 0, SURFACE_OPAQUE); 3136 } 3137 return this; 3138 } 3139 3140 /** 3141 * @hide 3142 */ setDisplaySurface(IBinder displayToken, Surface surface)3143 public Transaction setDisplaySurface(IBinder displayToken, Surface surface) { 3144 if (displayToken == null) { 3145 throw new IllegalArgumentException("displayToken must not be null"); 3146 } 3147 3148 if (surface != null) { 3149 synchronized (surface.mLock) { 3150 nativeSetDisplaySurface(mNativeObject, displayToken, surface.mNativeObject); 3151 } 3152 } else { 3153 nativeSetDisplaySurface(mNativeObject, displayToken, 0); 3154 } 3155 return this; 3156 } 3157 3158 /** 3159 * @hide 3160 */ setDisplayLayerStack(IBinder displayToken, int layerStack)3161 public Transaction setDisplayLayerStack(IBinder displayToken, int layerStack) { 3162 if (displayToken == null) { 3163 throw new IllegalArgumentException("displayToken must not be null"); 3164 } 3165 nativeSetDisplayLayerStack(mNativeObject, displayToken, layerStack); 3166 return this; 3167 } 3168 3169 /** 3170 * @hide 3171 */ setDisplayProjection(IBinder displayToken, int orientation, Rect layerStackRect, Rect displayRect)3172 public Transaction setDisplayProjection(IBinder displayToken, 3173 int orientation, Rect layerStackRect, Rect displayRect) { 3174 if (displayToken == null) { 3175 throw new IllegalArgumentException("displayToken must not be null"); 3176 } 3177 if (layerStackRect == null) { 3178 throw new IllegalArgumentException("layerStackRect must not be null"); 3179 } 3180 if (displayRect == null) { 3181 throw new IllegalArgumentException("displayRect must not be null"); 3182 } 3183 nativeSetDisplayProjection(mNativeObject, displayToken, orientation, 3184 layerStackRect.left, layerStackRect.top, layerStackRect.right, layerStackRect.bottom, 3185 displayRect.left, displayRect.top, displayRect.right, displayRect.bottom); 3186 return this; 3187 } 3188 3189 /** 3190 * @hide 3191 */ setDisplaySize(IBinder displayToken, int width, int height)3192 public Transaction setDisplaySize(IBinder displayToken, int width, int height) { 3193 if (displayToken == null) { 3194 throw new IllegalArgumentException("displayToken must not be null"); 3195 } 3196 if (width <= 0 || height <= 0) { 3197 throw new IllegalArgumentException("width and height must be positive"); 3198 } 3199 3200 nativeSetDisplaySize(mNativeObject, displayToken, width, height); 3201 return this; 3202 } 3203 3204 /** flag the transaction as an animation 3205 * @hide 3206 */ setAnimationTransaction()3207 public Transaction setAnimationTransaction() { 3208 nativeSetAnimationTransaction(mNativeObject); 3209 return this; 3210 } 3211 3212 /** 3213 * Provides a hint to SurfaceFlinger to change its offset so that SurfaceFlinger wakes up 3214 * earlier to compose surfaces. The caller should use this as a hint to SurfaceFlinger 3215 * when the scene is complex enough to use GPU composition. The hint will remain active 3216 * until until the client calls {@link Transaction#setEarlyWakeupEnd}. 3217 * 3218 * @hide 3219 */ setEarlyWakeupStart()3220 public Transaction setEarlyWakeupStart() { 3221 nativeSetEarlyWakeupStart(mNativeObject); 3222 return this; 3223 } 3224 3225 /** 3226 * Removes the early wake up hint set by {@link Transaction#setEarlyWakeupStart}. 3227 * 3228 * @hide 3229 */ setEarlyWakeupEnd()3230 public Transaction setEarlyWakeupEnd() { 3231 nativeSetEarlyWakeupEnd(mNativeObject); 3232 return this; 3233 } 3234 3235 /** 3236 * Sets an arbitrary piece of metadata on the surface. This is a helper for int data. 3237 * @hide 3238 */ setMetadata(SurfaceControl sc, int key, int data)3239 public Transaction setMetadata(SurfaceControl sc, int key, int data) { 3240 Parcel parcel = Parcel.obtain(); 3241 parcel.writeInt(data); 3242 try { 3243 setMetadata(sc, key, parcel); 3244 } finally { 3245 parcel.recycle(); 3246 } 3247 return this; 3248 } 3249 3250 /** 3251 * Sets an arbitrary piece of metadata on the surface. 3252 * @hide 3253 */ setMetadata(SurfaceControl sc, int key, Parcel data)3254 public Transaction setMetadata(SurfaceControl sc, int key, Parcel data) { 3255 checkPreconditions(sc); 3256 nativeSetMetadata(mNativeObject, sc.mNativeObject, key, data); 3257 return this; 3258 } 3259 3260 /** 3261 * Draws shadows of length {@code shadowRadius} around the surface {@link SurfaceControl}. 3262 * If the length is 0.0f then the shadows will not be drawn. 3263 * 3264 * Shadows are drawn around the screen bounds, these are the post transformed cropped 3265 * bounds. They can draw over their parent bounds and will be occluded by layers with a 3266 * higher z-order. The shadows will respect the surface's corner radius if the 3267 * rounded corner bounds (transformed source bounds) are within the screen bounds. 3268 * 3269 * A shadow will only be drawn on buffer and color layers. If the radius is applied on a 3270 * container layer, it will be passed down the hierarchy to be applied on buffer and color 3271 * layers but not its children. A scenario where this is useful is when SystemUI animates 3272 * a task by controlling a leash to it, can draw a shadow around the app surface by 3273 * setting a shadow on the leash. This is similar to how rounded corners are set. 3274 * 3275 * @hide 3276 */ setShadowRadius(SurfaceControl sc, float shadowRadius)3277 public Transaction setShadowRadius(SurfaceControl sc, float shadowRadius) { 3278 checkPreconditions(sc); 3279 nativeSetShadowRadius(mNativeObject, sc.mNativeObject, shadowRadius); 3280 return this; 3281 } 3282 3283 /** 3284 * Sets the intended frame rate for this surface. Any switching of refresh rates is 3285 * most probably going to be seamless. 3286 * 3287 * @see #setFrameRate(SurfaceControl, float, int, int) 3288 */ 3289 @NonNull setFrameRate(@onNull SurfaceControl sc, @FloatRange(from = 0.0) float frameRate, @Surface.FrameRateCompatibility int compatibility)3290 public Transaction setFrameRate(@NonNull SurfaceControl sc, 3291 @FloatRange(from = 0.0) float frameRate, 3292 @Surface.FrameRateCompatibility int compatibility) { 3293 return setFrameRate(sc, frameRate, compatibility, 3294 Surface.CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS); 3295 } 3296 3297 /** 3298 * Sets the intended frame rate for the surface {@link SurfaceControl}. 3299 * <p> 3300 * On devices that are capable of running the display at different refresh rates, the system 3301 * may choose a display refresh rate to better match this surface's frame rate. Usage of 3302 * this API won't directly affect the application's frame production pipeline. However, 3303 * because the system may change the display refresh rate, calls to this function may result 3304 * in changes to Choreographer callback timings, and changes to the time interval at which 3305 * the system releases buffers back to the application. 3306 * <p> 3307 * Note that this only has an effect for surfaces presented on the display. If this 3308 * surface is consumed by something other than the system compositor, e.g. a media 3309 * codec, this call has no effect. 3310 * 3311 * @param sc The SurfaceControl to specify the frame rate of. 3312 * @param frameRate The intended frame rate for this surface, in frames per second. 0 is a 3313 * special value that indicates the app will accept the system's choice for 3314 * the display frame rate, which is the default behavior if this function 3315 * isn't called. The <code>frameRate</code> param does <em>not</em> need 3316 * to be a valid refresh rate for this device's display - e.g., it's fine 3317 * to pass 30fps to a device that can only run the display at 60fps. 3318 * @param compatibility The frame rate compatibility of this surface. The compatibility 3319 * value may influence the system's choice of display frame rate. 3320 * This parameter is ignored when <code>frameRate</code> is 0. 3321 * @param changeFrameRateStrategy Whether display refresh rate transitions caused by this 3322 * surface should be seamless. A seamless transition is one 3323 * that doesn't have any visual interruptions, such as a 3324 * black screen for a second or two. This parameter is 3325 * ignored when <code>frameRate</code> is 0. 3326 * @return This transaction object. 3327 */ 3328 @NonNull setFrameRate(@onNull SurfaceControl sc, @FloatRange(from = 0.0) float frameRate, @Surface.FrameRateCompatibility int compatibility, @Surface.ChangeFrameRateStrategy int changeFrameRateStrategy)3329 public Transaction setFrameRate(@NonNull SurfaceControl sc, 3330 @FloatRange(from = 0.0) float frameRate, 3331 @Surface.FrameRateCompatibility int compatibility, 3332 @Surface.ChangeFrameRateStrategy int changeFrameRateStrategy) { 3333 checkPreconditions(sc); 3334 nativeSetFrameRate(mNativeObject, sc.mNativeObject, frameRate, compatibility, 3335 changeFrameRateStrategy); 3336 return this; 3337 } 3338 3339 /** 3340 * Sets focus on the window identified by the input {@code token} if the window is focusable 3341 * otherwise the request is dropped. 3342 * 3343 * If the window is not visible, the request will be queued until the window becomes 3344 * visible or the request is overrriden by another request. The currently focused window 3345 * will lose focus immediately. This is to send the newly focused window any focus 3346 * dispatched events that occur while it is completing its first draw. 3347 * 3348 * @hide 3349 */ setFocusedWindow(@onNull IBinder token, String windowName, int displayId)3350 public Transaction setFocusedWindow(@NonNull IBinder token, String windowName, 3351 int displayId) { 3352 nativeSetFocusedWindow(mNativeObject, token, windowName, 3353 null /* focusedToken */, null /* focusedWindowName */, displayId); 3354 return this; 3355 } 3356 3357 /** 3358 * Set focus on the window identified by the input {@code token} if the window identified by 3359 * the input {@code focusedToken} is currently focused. If the {@code focusedToken} does not 3360 * have focus, the request is dropped. 3361 * 3362 * This is used by forward focus transfer requests from clients that host embedded windows, 3363 * and want to transfer focus to/from them. 3364 * 3365 * @hide 3366 */ requestFocusTransfer(@onNull IBinder token, String windowName, @NonNull IBinder focusedToken, String focusedWindowName, int displayId)3367 public Transaction requestFocusTransfer(@NonNull IBinder token, 3368 String windowName, 3369 @NonNull IBinder focusedToken, 3370 String focusedWindowName, 3371 int displayId) { 3372 nativeSetFocusedWindow(mNativeObject, token, windowName, focusedToken, 3373 focusedWindowName, displayId); 3374 return this; 3375 } 3376 3377 /** 3378 * Adds or removes the flag SKIP_SCREENSHOT of the surface. Setting the flag is equivalent 3379 * to creating the Surface with the {@link #SKIP_SCREENSHOT} flag. 3380 * 3381 * @hide 3382 */ setSkipScreenshot(SurfaceControl sc, boolean skipScrenshot)3383 public Transaction setSkipScreenshot(SurfaceControl sc, boolean skipScrenshot) { 3384 checkPreconditions(sc); 3385 if (skipScrenshot) { 3386 nativeSetFlags(mNativeObject, sc.mNativeObject, SKIP_SCREENSHOT, SKIP_SCREENSHOT); 3387 } else { 3388 nativeSetFlags(mNativeObject, sc.mNativeObject, 0, SKIP_SCREENSHOT); 3389 } 3390 return this; 3391 } 3392 3393 /** 3394 * Set a buffer for a SurfaceControl. This can only be used for SurfaceControls that were 3395 * created as type {@link #FX_SURFACE_BLAST} 3396 * 3397 * @hide 3398 */ setBuffer(SurfaceControl sc, GraphicBuffer buffer)3399 public Transaction setBuffer(SurfaceControl sc, GraphicBuffer buffer) { 3400 checkPreconditions(sc); 3401 nativeSetBuffer(mNativeObject, sc.mNativeObject, buffer); 3402 return this; 3403 } 3404 3405 /** 3406 * Set the color space for the SurfaceControl. The supported color spaces are SRGB 3407 * and Display P3, other color spaces will be treated as SRGB. This can only be used for 3408 * SurfaceControls that were created as type {@link #FX_SURFACE_BLAST} 3409 * 3410 * @hide 3411 */ setColorSpace(SurfaceControl sc, ColorSpace colorSpace)3412 public Transaction setColorSpace(SurfaceControl sc, ColorSpace colorSpace) { 3413 checkPreconditions(sc); 3414 nativeSetColorSpace(mNativeObject, sc.mNativeObject, colorSpace.getId()); 3415 return this; 3416 } 3417 3418 /** 3419 * Sets the trusted overlay state on this SurfaceControl and it is inherited to all the 3420 * children. The caller must hold the ACCESS_SURFACE_FLINGER permission. 3421 * @hide 3422 */ setTrustedOverlay(SurfaceControl sc, boolean isTrustedOverlay)3423 public Transaction setTrustedOverlay(SurfaceControl sc, boolean isTrustedOverlay) { 3424 checkPreconditions(sc); 3425 nativeSetTrustedOverlay(mNativeObject, sc.mNativeObject, isTrustedOverlay); 3426 return this; 3427 } 3428 3429 /** 3430 * Merge the other transaction into this transaction, clearing the 3431 * other transaction as if it had been applied. 3432 * 3433 * @param other The transaction to merge in to this one. 3434 * @return This transaction. 3435 */ 3436 @NonNull merge(@onNull Transaction other)3437 public Transaction merge(@NonNull Transaction other) { 3438 if (this == other) { 3439 return this; 3440 } 3441 mResizedSurfaces.putAll(other.mResizedSurfaces); 3442 other.mResizedSurfaces.clear(); 3443 mReparentedSurfaces.putAll(other.mReparentedSurfaces); 3444 other.mReparentedSurfaces.clear(); 3445 nativeMergeTransaction(mNativeObject, other.mNativeObject); 3446 return this; 3447 } 3448 3449 /** 3450 * Equivalent to reparent with a null parent, in that it removes 3451 * the SurfaceControl from the scene, but it also releases 3452 * the local resources (by calling {@link SurfaceControl#release}) 3453 * after this method returns, {@link SurfaceControl#isValid} will return 3454 * false for the argument. 3455 * 3456 * @param sc The surface to remove and release. 3457 * @return This transaction 3458 * @hide 3459 */ 3460 @NonNull remove(@onNull SurfaceControl sc)3461 public Transaction remove(@NonNull SurfaceControl sc) { 3462 reparent(sc, null); 3463 sc.release(); 3464 return this; 3465 } 3466 3467 /** 3468 * Sets the frame timeline vsync id received from choreographer 3469 * {@link Choreographer#getVsyncId()} that corresponds to the transaction submitted on that 3470 * surface control. 3471 * 3472 * @hide 3473 */ 3474 @NonNull setFrameTimelineVsync(long frameTimelineVsyncId)3475 public Transaction setFrameTimelineVsync(long frameTimelineVsyncId) { 3476 nativeSetFrameTimelineVsync(mNativeObject, frameTimelineVsyncId); 3477 return this; 3478 } 3479 3480 /** 3481 * Writes the transaction to parcel, clearing the transaction as if it had been applied so 3482 * it can be used to store future transactions. It's the responsibility of the parcel 3483 * reader to apply the original transaction. 3484 * 3485 * @param dest parcel to write the transaction to 3486 * @param flags 3487 */ 3488 @Override writeToParcel(@onNull Parcel dest, @WriteFlags int flags)3489 public void writeToParcel(@NonNull Parcel dest, @WriteFlags int flags) { 3490 if (mNativeObject == 0) { 3491 dest.writeInt(0); 3492 return; 3493 } 3494 3495 dest.writeInt(1); 3496 nativeWriteTransactionToParcel(mNativeObject, dest); 3497 if ((flags & Parcelable.PARCELABLE_WRITE_RETURN_VALUE) != 0) { 3498 nativeClearTransaction(mNativeObject); 3499 } 3500 } 3501 readFromParcel(Parcel in)3502 private void readFromParcel(Parcel in) { 3503 mNativeObject = 0; 3504 if (in.readInt() != 0) { 3505 mNativeObject = nativeReadTransactionFromParcel(in); 3506 mFreeNativeResources = sRegistry.registerNativeAllocation(this, mNativeObject); 3507 } 3508 } 3509 3510 @Override describeContents()3511 public int describeContents() { 3512 return 0; 3513 } 3514 3515 public static final @NonNull Creator<Transaction> CREATOR = new Creator<Transaction>() { 3516 @Override 3517 public Transaction createFromParcel(Parcel in) { 3518 return new Transaction(in); 3519 } 3520 @Override 3521 public Transaction[] newArray(int size) { 3522 return new Transaction[size]; 3523 } 3524 }; 3525 } 3526 3527 /** 3528 * A debugging utility subclass of SurfaceControl.Transaction. At construction 3529 * you can pass in a monitor object, and all the other methods will throw an exception 3530 * if the monitor is not held when they are called. 3531 * @hide 3532 */ 3533 public static class LockDebuggingTransaction extends SurfaceControl.Transaction { 3534 Object mMonitor; 3535 LockDebuggingTransaction(Object o)3536 public LockDebuggingTransaction(Object o) { 3537 mMonitor = o; 3538 } 3539 3540 @Override checkPreconditions(SurfaceControl sc)3541 protected void checkPreconditions(SurfaceControl sc) { 3542 super.checkPreconditions(sc); 3543 if (!Thread.holdsLock(mMonitor)) { 3544 throw new RuntimeException( 3545 "Unlocked access to synchronized SurfaceControl.Transaction"); 3546 } 3547 } 3548 } 3549 3550 /** 3551 * As part of eliminating usage of the global Transaction we expose 3552 * a SurfaceControl.getGlobalTransaction function. However calling 3553 * apply on this global transaction (rather than using closeTransaction) 3554 * would be very dangerous. So for the global transaction we use this 3555 * subclass of Transaction where the normal apply throws an exception. 3556 */ 3557 private static class GlobalTransactionWrapper extends SurfaceControl.Transaction { applyGlobalTransaction(boolean sync)3558 void applyGlobalTransaction(boolean sync) { 3559 applyResizedSurfaces(); 3560 notifyReparentedSurfaces(); 3561 nativeApplyTransaction(mNativeObject, sync); 3562 } 3563 3564 @Override apply(boolean sync)3565 public void apply(boolean sync) { 3566 throw new RuntimeException("Global transaction must be applied from closeTransaction"); 3567 } 3568 } 3569 3570 /** 3571 * Acquire a frame rate flexibility token, which allows surface flinger to freely switch display 3572 * frame rates. This is used by CTS tests to put the device in a consistent state. See 3573 * ISurfaceComposer::acquireFrameRateFlexibilityToken(). The caller must have the 3574 * ACCESS_SURFACE_FLINGER permission, or else the call will fail, returning 0. 3575 * @hide 3576 */ 3577 @TestApi acquireFrameRateFlexibilityToken()3578 public static long acquireFrameRateFlexibilityToken() { 3579 return nativeAcquireFrameRateFlexibilityToken(); 3580 } 3581 3582 /** 3583 * Release a frame rate flexibility token. 3584 * @hide 3585 */ 3586 @TestApi releaseFrameRateFlexibilityToken(long token)3587 public static void releaseFrameRateFlexibilityToken(long token) { 3588 nativeReleaseFrameRateFlexibilityToken(token); 3589 } 3590 3591 /** 3592 * This is a refactoring utility function to enable lower levels of code to be refactored 3593 * from using the global transaction (and instead use a passed in Transaction) without 3594 * having to refactor the higher levels at the same time. 3595 * The returned global transaction can't be applied, it must be applied from closeTransaction 3596 * Unless you are working on removing Global Transaction usage in the WindowManager, this 3597 * probably isn't a good function to use. 3598 * @hide 3599 */ getGlobalTransaction()3600 public static Transaction getGlobalTransaction() { 3601 return sGlobalTransaction; 3602 } 3603 3604 /** 3605 * @hide 3606 */ resize(int w, int h)3607 public void resize(int w, int h) { 3608 mWidth = w; 3609 mHeight = h; 3610 nativeUpdateDefaultBufferSize(mNativeObject, w, h); 3611 } 3612 3613 /** 3614 * @hide 3615 */ getTransformHint()3616 public int getTransformHint() { 3617 checkNotReleased(); 3618 return nativeGetTransformHint(mNativeObject); 3619 } 3620 3621 /** 3622 * Update the transform hint of current SurfaceControl. Only affect if type is 3623 * {@link #FX_SURFACE_BLAST} 3624 * 3625 * The transform hint is used to prevent allocating a buffer of different size when a 3626 * layer is rotated. The producer can choose to consume the hint and allocate the buffer 3627 * with the same size. 3628 * @hide 3629 */ setTransformHint(@urface.Rotation int transformHint)3630 public void setTransformHint(@Surface.Rotation int transformHint) { 3631 nativeSetTransformHint(mNativeObject, transformHint); 3632 } 3633 } 3634