summaryrefslogtreecommitdiff
path: root/libs/gui
diff options
context:
space:
mode:
author Xin Li <delphij@google.com> 2023-10-06 05:34:14 +0000
committer Gerrit Code Review <noreply-gerritcodereview@google.com> 2023-10-06 05:34:14 +0000
commit8b919d0eb0e816bdd67f11855e649ce3723930ee (patch)
treeb9785db180fb54b3a776f645cbb2a7ef480e0cb9 /libs/gui
parente4b64ebecf894e3047e46894a83ab8d37feabd3e (diff)
parent1961b2f7b191744f3fc6bb4d32f0da0ce3ee0567 (diff)
Merge "Merge Android 14" into main
Diffstat (limited to 'libs/gui')
-rw-r--r--libs/gui/Android.bp74
-rw-r--r--libs/gui/BLASTBufferQueue.cpp237
-rw-r--r--libs/gui/BufferQueueConsumer.cpp3
-rw-r--r--libs/gui/BufferQueueProducer.cpp17
-rw-r--r--libs/gui/Choreographer.cpp397
-rw-r--r--libs/gui/CompositorTiming.cpp54
-rw-r--r--libs/gui/DisplayEventDispatcher.cpp14
-rw-r--r--libs/gui/DisplayEventReceiver.cpp27
-rw-r--r--libs/gui/DisplayInfo.cpp18
-rw-r--r--libs/gui/FenceMonitor.cpp89
-rw-r--r--libs/gui/FrameTimelineInfo.cpp68
-rw-r--r--libs/gui/GLConsumerUtils.cpp11
-rw-r--r--libs/gui/ISurfaceComposer.cpp1607
-rw-r--r--libs/gui/ISurfaceComposerClient.cpp124
-rw-r--r--libs/gui/ITransactionCompletedListener.cpp68
-rw-r--r--libs/gui/LayerDebugInfo.cpp4
-rw-r--r--libs/gui/LayerMetadata.cpp4
-rw-r--r--libs/gui/LayerState.cpp294
-rw-r--r--libs/gui/LayerStatePermissions.cpp58
-rw-r--r--libs/gui/ScreenCaptureResults.cpp17
-rw-r--r--libs/gui/Surface.cpp183
-rw-r--r--libs/gui/SurfaceComposerClient.cpp1163
-rw-r--r--libs/gui/SurfaceControl.cpp52
-rw-r--r--libs/gui/SyncFeatures.cpp10
-rw-r--r--libs/gui/TEST_MAPPING6
-rw-r--r--libs/gui/TransactionTracing.cpp53
-rw-r--r--libs/gui/VsyncEventData.cpp18
-rw-r--r--libs/gui/WindowInfo.cpp9
-rw-r--r--libs/gui/WindowInfosListenerReporter.cpp48
-rw-r--r--libs/gui/WindowInfosUpdate.cpp72
-rw-r--r--libs/gui/aidl/android/gui/ARect.aidl (renamed from libs/gui/aidl/android/gui/Rect.aidl)2
-rw-r--r--libs/gui/aidl/android/gui/CachingHint.aidl30
-rw-r--r--libs/gui/aidl/android/gui/Color.aidl25
-rw-r--r--libs/gui/aidl/android/gui/CompositionPreference.aidl25
-rw-r--r--libs/gui/aidl/android/gui/ContentSamplingAttributes.aidl24
-rw-r--r--libs/gui/aidl/android/gui/CreateSurfaceResult.aidl25
-rw-r--r--libs/gui/aidl/android/gui/DeviceProductInfo.aidl58
-rw-r--r--libs/gui/aidl/android/gui/DisplayConnectionType.aidl24
-rw-r--r--libs/gui/aidl/android/gui/DisplayDecorationSupport.aidl25
-rw-r--r--libs/gui/aidl/android/gui/DisplayMode.aidl37
-rw-r--r--libs/gui/aidl/android/gui/DisplayModeSpecs.aidl75
-rw-r--r--libs/gui/aidl/android/gui/DisplayPrimaries.aidl33
-rw-r--r--libs/gui/aidl/android/gui/DisplayedFrameStats.aidl40
-rw-r--r--libs/gui/aidl/android/gui/DynamicDisplayInfo.aidl46
-rw-r--r--libs/gui/aidl/android/gui/FrameEvent.aidl35
-rw-r--r--libs/gui/aidl/android/gui/FrameStats.aidl47
-rw-r--r--libs/gui/aidl/android/gui/FrameTimelineInfo.aidl (renamed from libs/gui/include/gui/FrameTimelineInfo.h)33
-rw-r--r--libs/gui/aidl/android/gui/HdrCapabilities.aidl27
-rw-r--r--libs/gui/aidl/android/gui/HdrConversionCapability.aidl25
-rw-r--r--libs/gui/aidl/android/gui/HdrConversionStrategy.aidl25
-rw-r--r--libs/gui/aidl/android/gui/IHdrConversionConstants.aidl30
-rw-r--r--libs/gui/aidl/android/gui/IHdrLayerInfoListener.aidl6
-rw-r--r--libs/gui/aidl/android/gui/ISurfaceComposer.aidl365
-rw-r--r--libs/gui/aidl/android/gui/ISurfaceComposerClient.aidl63
-rw-r--r--libs/gui/aidl/android/gui/ITransactionTraceListener.aidl6
-rw-r--r--libs/gui/aidl/android/gui/LayerDebugInfo.aidl19
-rw-r--r--libs/gui/aidl/android/gui/LayerMetadata.aidl19
-rw-r--r--libs/gui/aidl/android/gui/OverlayProperties.aidl30
-rw-r--r--libs/gui/aidl/android/gui/PullAtomData.aidl23
-rw-r--r--libs/gui/aidl/android/gui/StaticDisplayInfo.aidl30
-rw-r--r--libs/gui/aidl/android/gui/TrustedPresentationThresholds.aidl24
-rw-r--r--libs/gui/aidl/android/gui/WindowInfosListenerInfo.aidl25
-rw-r--r--libs/gui/android/gui/FocusRequest.aidl9
-rw-r--r--libs/gui/android/gui/IWindowInfosListener.aidl9
-rw-r--r--libs/gui/android/gui/IWindowInfosPublisher.aidl23
-rw-r--r--libs/gui/android/gui/WindowInfosUpdate.aidl22
-rw-r--r--libs/gui/fuzzer/Android.bp136
-rw-r--r--libs/gui/fuzzer/README.md219
-rw-r--r--libs/gui/fuzzer/libgui_bufferQueue_fuzzer.cpp392
-rw-r--r--libs/gui/fuzzer/libgui_consumer_fuzzer.cpp82
-rw-r--r--libs/gui/fuzzer/libgui_displayEvent_fuzzer.cpp104
-rw-r--r--libs/gui/fuzzer/libgui_fuzzer_utils.h315
-rw-r--r--libs/gui/fuzzer/libgui_parcelable_fuzzer.cpp175
-rw-r--r--libs/gui/fuzzer/libgui_surfaceComposerClient_fuzzer.cpp327
-rw-r--r--libs/gui/fuzzer/libgui_surfaceComposer_fuzzer.cpp41
-rw-r--r--libs/gui/include/gui/AidlStatusUtil.h114
-rw-r--r--libs/gui/include/gui/BLASTBufferQueue.h48
-rw-r--r--libs/gui/include/gui/Choreographer.h140
-rw-r--r--libs/gui/include/gui/CompositorTiming.h43
-rw-r--r--libs/gui/include/gui/DisplayCaptureArgs.h16
-rw-r--r--libs/gui/include/gui/DisplayEventDispatcher.h9
-rw-r--r--libs/gui/include/gui/DisplayEventReceiver.h15
-rw-r--r--libs/gui/include/gui/DisplayInfo.h2
-rw-r--r--libs/gui/include/gui/FenceMonitor.h44
-rw-r--r--libs/gui/include/gui/FrameTimestamps.h27
-rw-r--r--libs/gui/include/gui/GLConsumer.h4
-rw-r--r--libs/gui/include/gui/ISurfaceComposer.h450
-rw-r--r--libs/gui/include/gui/ISurfaceComposerClient.h97
-rw-r--r--libs/gui/include/gui/ITransactionCompletedListener.h18
-rw-r--r--libs/gui/include/gui/JankInfo.h4
-rw-r--r--libs/gui/include/gui/LayerCaptureArgs.h3
-rw-r--r--libs/gui/include/gui/LayerDebugInfo.h6
-rw-r--r--libs/gui/include/gui/LayerMetadata.h19
-rw-r--r--libs/gui/include/gui/LayerState.h137
-rw-r--r--libs/gui/include/gui/LayerStatePermissions.h (renamed from libs/gui/include/gui/TransactionTracing.h)28
-rw-r--r--libs/gui/include/gui/ScreenCaptureResults.h4
-rw-r--r--libs/gui/include/gui/Surface.h12
-rw-r--r--libs/gui/include/gui/SurfaceComposerClient.h217
-rw-r--r--libs/gui/include/gui/SurfaceControl.h19
-rw-r--r--libs/gui/include/gui/SyncScreenCaptureListener.h6
-rw-r--r--libs/gui/include/gui/TraceUtils.h28
-rw-r--r--libs/gui/include/gui/VsyncEventData.h11
-rw-r--r--libs/gui/include/gui/WindowInfo.h10
-rw-r--r--libs/gui/include/gui/WindowInfosListener.h8
-rw-r--r--libs/gui/include/gui/WindowInfosListenerReporter.h23
-rw-r--r--libs/gui/include/gui/WindowInfosUpdate.h44
-rw-r--r--libs/gui/include/gui/fake/BufferData.h51
-rw-r--r--libs/gui/include/gui/test/CallbackUtils.h30
-rw-r--r--libs/gui/include/private/gui/ComposerServiceAIDL.h23
-rw-r--r--libs/gui/tests/Android.bp1
-rw-r--r--libs/gui/tests/BLASTBufferQueue_test.cpp70
-rw-r--r--libs/gui/tests/BufferItemConsumer_test.cpp10
-rw-r--r--libs/gui/tests/BufferQueue_test.cpp4
-rw-r--r--libs/gui/tests/CompositorTiming_test.cpp61
-rw-r--r--libs/gui/tests/CpuConsumer_test.cpp20
-rw-r--r--libs/gui/tests/DisplayEventStructLayout_test.cpp9
-rw-r--r--libs/gui/tests/DisplayedContentSampling_test.cpp5
-rw-r--r--libs/gui/tests/EndToEndNativeInputTest.cpp70
-rw-r--r--libs/gui/tests/GLTest.cpp4
-rw-r--r--libs/gui/tests/IGraphicBufferProducer_test.cpp4
-rw-r--r--libs/gui/tests/RegionSampling_test.cpp102
-rw-r--r--libs/gui/tests/SamplingDemo.cpp20
-rw-r--r--libs/gui/tests/StreamSplitter_test.cpp4
-rw-r--r--libs/gui/tests/SurfaceTextureClient_test.cpp4
-rw-r--r--libs/gui/tests/Surface_test.cpp457
-rw-r--r--libs/gui/tests/VsyncEventData_test.cpp4
-rw-r--r--libs/gui/tests/WindowInfo_test.cpp4
127 files changed, 6910 insertions, 3607 deletions
diff --git a/libs/gui/Android.bp b/libs/gui/Android.bp
index 0fe6f24842..d7e7eb8ea1 100644
--- a/libs/gui/Android.bp
+++ b/libs/gui/Android.bp
@@ -66,6 +66,20 @@ filegroup {
],
}
+filegroup {
+ name: "android_gui_aidl",
+ srcs: [
+ "android/gui/DisplayInfo.aidl",
+ "android/gui/FocusRequest.aidl",
+ "android/gui/InputApplicationInfo.aidl",
+ "android/gui/IWindowInfosListener.aidl",
+ "android/gui/IWindowInfosPublisher.aidl",
+ "android/gui/IWindowInfosReportedListener.aidl",
+ "android/gui/WindowInfo.aidl",
+ "android/gui/WindowInfosUpdate.aidl",
+ ],
+}
+
cc_library_static {
name: "libgui_window_info_static",
vendor_available: true,
@@ -77,10 +91,13 @@ cc_library_static {
"android/gui/FocusRequest.aidl",
"android/gui/InputApplicationInfo.aidl",
"android/gui/IWindowInfosListener.aidl",
+ "android/gui/IWindowInfosPublisher.aidl",
"android/gui/IWindowInfosReportedListener.aidl",
+ "android/gui/WindowInfosUpdate.aidl",
"android/gui/WindowInfo.aidl",
"DisplayInfo.cpp",
"WindowInfo.cpp",
+ "WindowInfosUpdate.cpp",
],
shared_libs: [
@@ -114,18 +131,36 @@ cc_library_static {
},
}
-filegroup {
+aidl_library {
+ name: "libgui_aidl_hdrs",
+ hdrs: [
+ "android/gui/DisplayInfo.aidl",
+ "android/gui/FocusRequest.aidl",
+ "android/gui/InputApplicationInfo.aidl",
+ "android/gui/IWindowInfosListener.aidl",
+ "android/gui/IWindowInfosPublisher.aidl",
+ "android/gui/IWindowInfosReportedListener.aidl",
+ "android/gui/WindowInfo.aidl",
+ "android/gui/WindowInfosUpdate.aidl",
+ ],
+}
+
+aidl_library {
name: "libgui_aidl",
srcs: ["aidl/**/*.aidl"],
+ strip_import_prefix: "aidl",
+ deps: ["libgui_aidl_hdrs"],
+}
+
+filegroup {
+ name: "libgui_frame_event_aidl",
+ srcs: ["aidl/android/gui/FrameEvent.aidl"],
path: "aidl/",
}
cc_library_static {
name: "libgui_aidl_static",
vendor_available: true,
- srcs: [
- ":libgui_aidl",
- ],
shared_libs: [
"libbinder",
@@ -136,16 +171,22 @@ cc_library_static {
"include",
],
+ include_dirs: [
+ "frameworks/native/include",
+ ],
+
export_shared_lib_headers: [
"libbinder",
],
static_libs: [
"libui-types",
+ "libgui_window_info_static",
],
aidl: {
export_aidl_headers: true,
+ libs: ["libgui_aidl"],
},
}
@@ -178,22 +219,24 @@ cc_library_shared {
"BitTube.cpp",
"BLASTBufferQueue.cpp",
"BufferItemConsumer.cpp",
+ "Choreographer.cpp",
+ "CompositorTiming.cpp",
"ConsumerBase.cpp",
"CpuConsumer.cpp",
"DebugEGLImageTracker.cpp",
"DisplayEventDispatcher.cpp",
"DisplayEventReceiver.cpp",
- "FrameTimelineInfo.cpp",
+ "FenceMonitor.cpp",
"GLConsumer.cpp",
"IConsumerListener.cpp",
"IGraphicBufferConsumer.cpp",
"IGraphicBufferProducer.cpp",
"IProducerListener.cpp",
"ISurfaceComposer.cpp",
- "ISurfaceComposerClient.cpp",
"ITransactionCompletedListener.cpp",
"LayerDebugInfo.cpp",
"LayerMetadata.cpp",
+ "LayerStatePermissions.cpp",
"LayerState.cpp",
"OccupancyTracker.cpp",
"StreamSplitter.cpp",
@@ -202,7 +245,6 @@ cc_library_shared {
"SurfaceControl.cpp",
"SurfaceComposerClient.cpp",
"SyncFeatures.cpp",
- "TransactionTracing.cpp",
"VsyncEventData.cpp",
"view/Surface.cpp",
"WindowInfosListenerReporter.cpp",
@@ -223,6 +265,7 @@ cc_library_shared {
export_header_lib_headers: [
"libgui_aidl_headers",
+ "jni_headers",
],
aidl: {
@@ -230,6 +273,7 @@ cc_library_shared {
},
header_libs: [
+ "jni_headers",
"libdvr_headers",
"libgui_aidl_headers",
"libpdx_headers",
@@ -240,6 +284,10 @@ cc_library_shared {
lto: {
thin: true,
},
+
+ cflags: [
+ "-Wthread-safety",
+ ],
}
// Used by media codec services exclusively as a static lib for
@@ -260,10 +308,16 @@ cc_library_static {
defaults: ["libgui_bufferqueue-defaults"],
srcs: [
+ ":libgui_frame_event_aidl",
":inputconstants_aidl",
":libgui_bufferqueue_sources",
- ":libgui_aidl",
],
+
+ aidl: {
+ include_dirs: [
+ "frameworks/native/libs/gui",
+ ],
+ },
}
filegroup {
@@ -294,6 +348,8 @@ filegroup {
cc_defaults {
name: "libgui_bufferqueue-defaults",
+ defaults: ["android.hardware.graphics.common-ndk_shared"],
+
cflags: [
"-Wall",
"-Werror",
@@ -322,7 +378,6 @@ cc_defaults {
"android.hardware.graphics.bufferqueue@2.0",
"android.hardware.graphics.common@1.1",
"android.hardware.graphics.common@1.2",
- "android.hardware.graphics.common-V4-ndk",
"android.hidl.token@1.0-utils",
"libbase",
"libcutils",
@@ -381,6 +436,7 @@ cc_library_static {
],
srcs: [
+ ":libgui_frame_event_aidl",
"mock/GraphicBufferConsumer.cpp",
"mock/GraphicBufferProducer.cpp",
],
diff --git a/libs/gui/BLASTBufferQueue.cpp b/libs/gui/BLASTBufferQueue.cpp
index 000f458fd1..5c324b29cd 100644
--- a/libs/gui/BLASTBufferQueue.cpp
+++ b/libs/gui/BLASTBufferQueue.cpp
@@ -20,6 +20,7 @@
#define ATRACE_TAG ATRACE_TAG_GRAPHICS
//#define LOG_NDEBUG 0
+#include <cutils/atomic.h>
#include <gui/BLASTBufferQueue.h>
#include <gui/BufferItemConsumer.h>
#include <gui/BufferQueueConsumer.h>
@@ -33,7 +34,9 @@
#include <utils/Trace.h>
#include <private/gui/ComposerService.h>
+#include <private/gui/ComposerServiceAIDL.h>
+#include <android-base/thread_annotations.h>
#include <chrono>
using namespace std::chrono_literals;
@@ -62,6 +65,10 @@ namespace android {
ATRACE_FORMAT("%s - %s(f:%u,a:%u)" x, __FUNCTION__, mName.c_str(), mNumFrameAvailable, \
mNumAcquired, ##__VA_ARGS__)
+#define UNIQUE_LOCK_WITH_ASSERTION(mutex) \
+ std::unique_lock _lock{mutex}; \
+ base::ScopedLockAssertion assumeLocked(mutex);
+
void BLASTBufferItemConsumer::onDisconnect() {
Mutex::Autolock lock(mMutex);
mPreviouslyConnected = mCurrentlyConnected;
@@ -156,30 +163,30 @@ BLASTBufferQueue::BLASTBufferQueue(const std::string& name, bool updateDestinati
GraphicBuffer::USAGE_HW_COMPOSER |
GraphicBuffer::USAGE_HW_TEXTURE,
1, false, this);
- static int32_t id = 0;
- mName = name + "#" + std::to_string(id);
- auto consumerName = mName + "(BLAST Consumer)" + std::to_string(id);
- mQueuedBufferTrace = "QueuedBuffer - " + mName + "BLAST#" + std::to_string(id);
- id++;
+ static std::atomic<uint32_t> nextId = 0;
+ mProducerId = nextId++;
+ mName = name + "#" + std::to_string(mProducerId);
+ auto consumerName = mName + "(BLAST Consumer)" + std::to_string(mProducerId);
+ mQueuedBufferTrace = "QueuedBuffer - " + mName + "BLAST#" + std::to_string(mProducerId);
mBufferItemConsumer->setName(String8(consumerName.c_str()));
mBufferItemConsumer->setFrameAvailableListener(this);
- mBufferItemConsumer->setBufferFreedListener(this);
- ComposerService::getComposerService()->getMaxAcquiredBufferCount(&mMaxAcquiredBuffers);
+ ComposerServiceAIDL::getComposerService()->getMaxAcquiredBufferCount(&mMaxAcquiredBuffers);
mBufferItemConsumer->setMaxAcquiredBufferCount(mMaxAcquiredBuffers);
mCurrentMaxAcquiredBufferCount = mMaxAcquiredBuffers;
mNumAcquired = 0;
mNumFrameAvailable = 0;
TransactionCompletedListener::getInstance()->addQueueStallListener(
- [&]() {
- std::function<void(bool)> callbackCopy;
- {
- std::unique_lock _lock{mMutex};
- callbackCopy = mTransactionHangCallback;
- }
- if (callbackCopy) callbackCopy(true);
- }, this);
+ [&](const std::string& reason) {
+ std::function<void(const std::string&)> callbackCopy;
+ {
+ std::unique_lock _lock{mMutex};
+ callbackCopy = mTransactionHangCallback;
+ }
+ if (callbackCopy) callbackCopy(reason);
+ },
+ this);
BQA_LOGV("BLASTBufferQueue created");
}
@@ -211,7 +218,7 @@ void BLASTBufferQueue::update(const sp<SurfaceControl>& surface, uint32_t width,
int32_t format) {
LOG_ALWAYS_FATAL_IF(surface == nullptr, "BLASTBufferQueue: mSurfaceControl must not be NULL");
- std::unique_lock _lock{mMutex};
+ std::lock_guard _lock{mMutex};
if (mFormat != format) {
mFormat = format;
mBufferItemConsumer->setDefaultBufferFormat(convertBufferFormat(format));
@@ -281,7 +288,7 @@ void BLASTBufferQueue::transactionCommittedCallback(nsecs_t /*latchTime*/,
const sp<Fence>& /*presentFence*/,
const std::vector<SurfaceControlStats>& stats) {
{
- std::unique_lock _lock{mMutex};
+ std::lock_guard _lock{mMutex};
BBQ_TRACE();
BQA_LOGV("transactionCommittedCallback");
if (!mSurfaceControlsWithPendingCallback.empty()) {
@@ -329,7 +336,7 @@ static void transactionCallbackThunk(void* context, nsecs_t latchTime,
void BLASTBufferQueue::transactionCallback(nsecs_t /*latchTime*/, const sp<Fence>& /*presentFence*/,
const std::vector<SurfaceControlStats>& stats) {
{
- std::unique_lock _lock{mMutex};
+ std::lock_guard _lock{mMutex};
BBQ_TRACE();
BQA_LOGV("transactionCallback");
@@ -339,9 +346,11 @@ void BLASTBufferQueue::transactionCallback(nsecs_t /*latchTime*/, const sp<Fence
std::optional<SurfaceControlStats> statsOptional = findMatchingStat(stats, pendingSC);
if (statsOptional) {
SurfaceControlStats stat = *statsOptional;
- mTransformHint = stat.transformHint;
- mBufferItemConsumer->setTransformHint(mTransformHint);
- BQA_LOGV("updated mTransformHint=%d", mTransformHint);
+ if (stat.transformHint) {
+ mTransformHint = *stat.transformHint;
+ mBufferItemConsumer->setTransformHint(mTransformHint);
+ BQA_LOGV("updated mTransformHint=%d", mTransformHint);
+ }
// Update frametime stamps if the frame was latched and presented, indicated by a
// valid latch time.
if (stat.latchTime > 0) {
@@ -408,9 +417,8 @@ void BLASTBufferQueue::flushShadowQueue() {
void BLASTBufferQueue::releaseBufferCallback(
const ReleaseCallbackId& id, const sp<Fence>& releaseFence,
std::optional<uint32_t> currentMaxAcquiredBufferCount) {
+ std::lock_guard _lock{mMutex};
BBQ_TRACE();
-
- std::unique_lock _lock{mMutex};
releaseBufferCallbackLocked(id, releaseFence, currentMaxAcquiredBufferCount,
false /* fakeRelease */);
}
@@ -425,10 +433,8 @@ void BLASTBufferQueue::releaseBufferCallbackLocked(
// to the buffer queue. This will prevent higher latency when we are running
// on a lower refresh rate than the max supported. We only do that for EGL
// clients as others don't care about latency
- const bool isEGL = [&] {
- const auto it = mSubmitted.find(id);
- return it != mSubmitted.end() && it->second.mApi == NATIVE_WINDOW_API_EGL;
- }();
+ const auto it = mSubmitted.find(id);
+ const bool isEGL = it != mSubmitted.end() && it->second.mApi == NATIVE_WINDOW_API_EGL;
if (currentMaxAcquiredBufferCount) {
mCurrentMaxAcquiredBufferCount = *currentMaxAcquiredBufferCount;
@@ -485,6 +491,17 @@ void BLASTBufferQueue::releaseBuffer(const ReleaseCallbackId& callbackId,
mSyncedFrameNumbers.erase(callbackId.framenumber);
}
+static ui::Size getBufferSize(const BufferItem& item) {
+ uint32_t bufWidth = item.mGraphicBuffer->getWidth();
+ uint32_t bufHeight = item.mGraphicBuffer->getHeight();
+
+ // Take the buffer's orientation into account
+ if (item.mTransform & ui::Transform::ROT_90) {
+ std::swap(bufWidth, bufHeight);
+ }
+ return ui::Size(bufWidth, bufHeight);
+}
+
status_t BLASTBufferQueue::acquireNextBufferLocked(
const std::optional<SurfaceComposerClient::Transaction*> transaction) {
// Check if we have frames available and we have not acquired the maximum number of buffers.
@@ -562,7 +579,13 @@ status_t BLASTBufferQueue::acquireNextBufferLocked(
// Ensure BLASTBufferQueue stays alive until we receive the transaction complete callback.
incStrong((void*)transactionCallbackThunk);
- mSize = mRequestedSize;
+ // Only update mSize for destination bounds if the incoming buffer matches the requested size.
+ // Otherwise, it could cause stretching since the destination bounds will update before the
+ // buffer with the new size is acquired.
+ if (mRequestedSize == getBufferSize(bufferItem) ||
+ bufferItem.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE) {
+ mSize = mRequestedSize;
+ }
Rect crop = computeCrop(bufferItem);
mLastBufferInfo.update(true /* hasBuffer */, bufferItem.mGraphicBuffer->getWidth(),
bufferItem.mGraphicBuffer->getHeight(), bufferItem.mTransform,
@@ -572,7 +595,8 @@ status_t BLASTBufferQueue::acquireNextBufferLocked(
std::bind(releaseBufferCallbackThunk, wp<BLASTBufferQueue>(this) /* callbackContext */,
std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
sp<Fence> fence = bufferItem.mFence ? new Fence(bufferItem.mFence->dup()) : Fence::NO_FENCE;
- t->setBuffer(mSurfaceControl, buffer, fence, bufferItem.mFrameNumber, releaseBufferCallback);
+ t->setBuffer(mSurfaceControl, buffer, fence, bufferItem.mFrameNumber, mProducerId,
+ releaseBufferCallback);
t->setDataspace(mSurfaceControl, static_cast<ui::Dataspace>(bufferItem.mDataSpace));
t->setHdrMetadata(mSurfaceControl, bufferItem.mHdrMetadata);
t->setSurfaceDamageRegion(mSurfaceControl, bufferItem.mSurfaceDamage);
@@ -617,12 +641,12 @@ status_t BLASTBufferQueue::acquireNextBufferLocked(
}
{
- std::unique_lock _lock{mTimestampMutex};
+ std::lock_guard _lock{mTimestampMutex};
auto dequeueTime = mDequeueTimestamps.find(buffer->getId());
if (dequeueTime != mDequeueTimestamps.end()) {
Parcel p;
p.writeInt64(dequeueTime->second);
- t->setMetadata(mSurfaceControl, METADATA_DEQUEUE_TIME, p);
+ t->setMetadata(mSurfaceControl, gui::METADATA_DEQUEUE_TIME, p);
mDequeueTimestamps.erase(dequeueTime);
}
}
@@ -656,6 +680,7 @@ Rect BLASTBufferQueue::computeCrop(const BufferItem& item) {
}
void BLASTBufferQueue::acquireAndReleaseBuffer() {
+ BBQ_TRACE();
BufferItem bufferItem;
status_t status =
mBufferItemConsumer->acquireBuffer(&bufferItem, 0 /* expectedPresent */, false);
@@ -673,10 +698,10 @@ void BLASTBufferQueue::onFrameAvailable(const BufferItem& item) {
SurfaceComposerClient::Transaction* prevTransaction = nullptr;
{
- std::unique_lock _lock{mMutex};
+ UNIQUE_LOCK_WITH_ASSERTION(mMutex);
BBQ_TRACE();
-
bool waitForTransactionCallback = !mSyncedFrameNumbers.empty();
+
const bool syncTransactionSet = mTransactionReadyCallback != nullptr;
BQA_LOGV("onFrameAvailable-start syncTransactionSet=%s", boolToString(syncTransactionSet));
@@ -767,44 +792,33 @@ void BLASTBufferQueue::onFrameReplaced(const BufferItem& item) {
}
void BLASTBufferQueue::onFrameDequeued(const uint64_t bufferId) {
- std::unique_lock _lock{mTimestampMutex};
+ std::lock_guard _lock{mTimestampMutex};
mDequeueTimestamps[bufferId] = systemTime();
};
void BLASTBufferQueue::onFrameCancelled(const uint64_t bufferId) {
- std::unique_lock _lock{mTimestampMutex};
+ std::lock_guard _lock{mTimestampMutex};
mDequeueTimestamps.erase(bufferId);
};
-void BLASTBufferQueue::syncNextTransaction(
+bool BLASTBufferQueue::syncNextTransaction(
std::function<void(SurfaceComposerClient::Transaction*)> callback,
bool acquireSingleBuffer) {
- BBQ_TRACE();
-
- std::function<void(SurfaceComposerClient::Transaction*)> prevCallback = nullptr;
- SurfaceComposerClient::Transaction* prevTransaction = nullptr;
-
- {
- std::lock_guard _lock{mMutex};
- // We're about to overwrite the previous call so we should invoke that callback
- // immediately.
- if (mTransactionReadyCallback) {
- prevCallback = mTransactionReadyCallback;
- prevTransaction = mSyncTransaction;
- }
+ LOG_ALWAYS_FATAL_IF(!callback,
+ "BLASTBufferQueue: callback passed in to syncNextTransaction must not be "
+ "NULL");
- mTransactionReadyCallback = callback;
- if (callback) {
- mSyncTransaction = new SurfaceComposerClient::Transaction();
- } else {
- mSyncTransaction = nullptr;
- }
- mAcquireSingleBuffer = mTransactionReadyCallback ? acquireSingleBuffer : true;
+ std::lock_guard _lock{mMutex};
+ BBQ_TRACE();
+ if (mTransactionReadyCallback) {
+ ALOGW("Attempting to overwrite transaction callback in syncNextTransaction");
+ return false;
}
- if (prevCallback) {
- prevCallback(prevTransaction);
- }
+ mTransactionReadyCallback = callback;
+ mSyncTransaction = new SurfaceComposerClient::Transaction();
+ mAcquireSingleBuffer = acquireSingleBuffer;
+ return true;
}
void BLASTBufferQueue::stopContinuousSyncTransaction() {
@@ -812,34 +826,42 @@ void BLASTBufferQueue::stopContinuousSyncTransaction() {
SurfaceComposerClient::Transaction* prevTransaction = nullptr;
{
std::lock_guard _lock{mMutex};
- bool invokeCallback = mTransactionReadyCallback && !mAcquireSingleBuffer;
- if (invokeCallback) {
- prevCallback = mTransactionReadyCallback;
- prevTransaction = mSyncTransaction;
+ if (mAcquireSingleBuffer || !mTransactionReadyCallback) {
+ ALOGW("Attempting to stop continuous sync when none are active");
+ return;
}
+
+ prevCallback = mTransactionReadyCallback;
+ prevTransaction = mSyncTransaction;
+
mTransactionReadyCallback = nullptr;
mSyncTransaction = nullptr;
mAcquireSingleBuffer = true;
}
+
if (prevCallback) {
prevCallback(prevTransaction);
}
}
+void BLASTBufferQueue::clearSyncTransaction() {
+ std::lock_guard _lock{mMutex};
+ if (!mAcquireSingleBuffer) {
+ ALOGW("Attempting to clear sync transaction when none are active");
+ return;
+ }
+
+ mTransactionReadyCallback = nullptr;
+ mSyncTransaction = nullptr;
+}
+
bool BLASTBufferQueue::rejectBuffer(const BufferItem& item) {
if (item.mScalingMode != NATIVE_WINDOW_SCALING_MODE_FREEZE) {
// Only reject buffers if scaling mode is freeze.
return false;
}
- uint32_t bufWidth = item.mGraphicBuffer->getWidth();
- uint32_t bufHeight = item.mGraphicBuffer->getHeight();
-
- // Take the buffer's orientation into account
- if (item.mTransform & ui::Transform::ROT_90) {
- std::swap(bufWidth, bufHeight);
- }
- ui::Size bufferSize(bufWidth, bufHeight);
+ ui::Size bufferSize = getBufferSize(item);
if (mRequestedSize != mSize && mRequestedSize == bufferSize) {
return false;
}
@@ -851,8 +873,8 @@ bool BLASTBufferQueue::rejectBuffer(const BufferItem& item) {
class BBQSurface : public Surface {
private:
std::mutex mMutex;
- sp<BLASTBufferQueue> mBbq;
- bool mDestroyed = false;
+ sp<BLASTBufferQueue> mBbq GUARDED_BY(mMutex);
+ bool mDestroyed GUARDED_BY(mMutex) = false;
public:
BBQSurface(const sp<IGraphicBufferProducer>& igbp, bool controlledByApp,
@@ -873,7 +895,7 @@ public:
status_t setFrameRate(float frameRate, int8_t compatibility,
int8_t changeFrameRateStrategy) override {
- std::unique_lock _lock{mMutex};
+ std::lock_guard _lock{mMutex};
if (mDestroyed) {
return DEAD_OBJECT;
}
@@ -886,7 +908,7 @@ public:
status_t setFrameTimelineInfo(uint64_t frameNumber,
const FrameTimelineInfo& frameTimelineInfo) override {
- std::unique_lock _lock{mMutex};
+ std::lock_guard _lock{mMutex};
if (mDestroyed) {
return DEAD_OBJECT;
}
@@ -896,7 +918,7 @@ public:
void destroy() override {
Surface::destroy();
- std::unique_lock _lock{mMutex};
+ std::lock_guard _lock{mMutex};
mDestroyed = true;
mBbq = nullptr;
}
@@ -906,7 +928,7 @@ public:
// no timing issues.
status_t BLASTBufferQueue::setFrameRate(float frameRate, int8_t compatibility,
bool shouldBeSeamless) {
- std::unique_lock _lock{mMutex};
+ std::lock_guard _lock{mMutex};
SurfaceComposerClient::Transaction t;
return t.setFrameRate(mSurfaceControl, frameRate, compatibility, shouldBeSeamless).apply();
@@ -916,20 +938,20 @@ status_t BLASTBufferQueue::setFrameTimelineInfo(uint64_t frameNumber,
const FrameTimelineInfo& frameTimelineInfo) {
ATRACE_FORMAT("%s(%s) frameNumber: %" PRIu64 " vsyncId: %" PRId64, __func__, mName.c_str(),
frameNumber, frameTimelineInfo.vsyncId);
- std::unique_lock _lock{mMutex};
+ std::lock_guard _lock{mMutex};
mPendingFrameTimelines.push({frameNumber, frameTimelineInfo});
return OK;
}
void BLASTBufferQueue::setSidebandStream(const sp<NativeHandle>& stream) {
- std::unique_lock _lock{mMutex};
+ std::lock_guard _lock{mMutex};
SurfaceComposerClient::Transaction t;
t.setSidebandStream(mSurfaceControl, stream).apply();
}
sp<Surface> BLASTBufferQueue::getSurface(bool includeSurfaceControlHandle) {
- std::unique_lock _lock{mMutex};
+ std::lock_guard _lock{mMutex};
sp<IBinder> scHandle = nullptr;
if (includeSurfaceControlHandle && mSurfaceControl) {
scHandle = mSurfaceControl->getHandle();
@@ -1154,6 +1176,7 @@ PixelFormat BLASTBufferQueue::convertBufferFormat(PixelFormat& format) {
}
uint32_t BLASTBufferQueue::getLastTransformHint() const {
+ std::lock_guard _lock{mMutex};
if (mSurfaceControl != nullptr) {
return mSurfaceControl->getTransformHint();
} else {
@@ -1162,62 +1185,18 @@ uint32_t BLASTBufferQueue::getLastTransformHint() const {
}
uint64_t BLASTBufferQueue::getLastAcquiredFrameNum() {
- std::unique_lock _lock{mMutex};
+ std::lock_guard _lock{mMutex};
return mLastAcquiredFrameNumber;
}
-void BLASTBufferQueue::abandon() {
- std::unique_lock _lock{mMutex};
- // flush out the shadow queue
- while (mNumFrameAvailable > 0) {
- acquireAndReleaseBuffer();
- }
-
- // Clear submitted buffer states
- mNumAcquired = 0;
- mSubmitted.clear();
- mPendingRelease.clear();
-
- if (!mPendingTransactions.empty()) {
- BQA_LOGD("Applying pending transactions on abandon %d",
- static_cast<uint32_t>(mPendingTransactions.size()));
- SurfaceComposerClient::Transaction t;
- mergePendingTransactions(&t, std::numeric_limits<uint64_t>::max() /* frameNumber */);
- // All transactions on our apply token are one-way. See comment on mAppliedLastTransaction
- t.setApplyToken(mApplyToken).apply(false, true);
- }
-
- // Clear sync states
- if (!mSyncedFrameNumbers.empty()) {
- BQA_LOGD("mSyncedFrameNumbers cleared");
- mSyncedFrameNumbers.clear();
- }
-
- if (mSyncTransaction != nullptr) {
- BQA_LOGD("mSyncTransaction cleared mAcquireSingleBuffer=%s",
- mAcquireSingleBuffer ? "true" : "false");
- mSyncTransaction = nullptr;
- mAcquireSingleBuffer = false;
- }
-
- // abandon buffer queue
- if (mBufferItemConsumer != nullptr) {
- mBufferItemConsumer->abandon();
- mBufferItemConsumer->setFrameAvailableListener(nullptr);
- mBufferItemConsumer->setBufferFreedListener(nullptr);
- }
- mBufferItemConsumer = nullptr;
- mConsumer = nullptr;
- mProducer = nullptr;
-}
-
bool BLASTBufferQueue::isSameSurfaceControl(const sp<SurfaceControl>& surfaceControl) const {
- std::unique_lock _lock{mMutex};
+ std::lock_guard _lock{mMutex};
return SurfaceControl::isSameSurface(mSurfaceControl, surfaceControl);
}
-void BLASTBufferQueue::setTransactionHangCallback(std::function<void(bool)> callback) {
- std::unique_lock _lock{mMutex};
+void BLASTBufferQueue::setTransactionHangCallback(
+ std::function<void(const std::string&)> callback) {
+ std::lock_guard _lock{mMutex};
mTransactionHangCallback = callback;
}
diff --git a/libs/gui/BufferQueueConsumer.cpp b/libs/gui/BufferQueueConsumer.cpp
index db513561fb..5b34ba12c8 100644
--- a/libs/gui/BufferQueueConsumer.cpp
+++ b/libs/gui/BufferQueueConsumer.cpp
@@ -33,6 +33,7 @@
#include <gui/BufferQueueCore.h>
#include <gui/IConsumerListener.h>
#include <gui/IProducerListener.h>
+#include <gui/TraceUtils.h>
#include <private/gui/BufferQueueThreadState.h>
#ifndef __ANDROID_VNDK__
@@ -645,7 +646,7 @@ status_t BufferQueueConsumer::setMaxBufferCount(int bufferCount) {
status_t BufferQueueConsumer::setMaxAcquiredBufferCount(
int maxAcquiredBuffers) {
- ATRACE_CALL();
+ ATRACE_FORMAT("%s(%d)", __func__, maxAcquiredBuffers);
if (maxAcquiredBuffers < 1 ||
maxAcquiredBuffers > BufferQueueCore::MAX_MAX_ACQUIRED_BUFFERS) {
diff --git a/libs/gui/BufferQueueProducer.cpp b/libs/gui/BufferQueueProducer.cpp
index 36c2e5891e..ce5d5d382e 100644
--- a/libs/gui/BufferQueueProducer.cpp
+++ b/libs/gui/BufferQueueProducer.cpp
@@ -35,6 +35,7 @@
#include <gui/GLConsumer.h>
#include <gui/IConsumerListener.h>
#include <gui/IProducerListener.h>
+#include <gui/TraceUtils.h>
#include <private/gui/BufferQueueThreadState.h>
#include <utils/Log.h>
@@ -125,7 +126,7 @@ status_t BufferQueueProducer::setMaxDequeuedBufferCount(
status_t BufferQueueProducer::setMaxDequeuedBufferCount(int maxDequeuedBuffers,
int* maxBufferCount) {
- ATRACE_CALL();
+ ATRACE_FORMAT("%s(%d)", __func__, maxDequeuedBuffers);
BQ_LOGV("setMaxDequeuedBufferCount: maxDequeuedBuffers = %d",
maxDequeuedBuffers);
@@ -502,6 +503,20 @@ status_t BufferQueueProducer::dequeueBuffer(int* outSlot, sp<android::Fence>* ou
if ((buffer == nullptr) ||
buffer->needsReallocation(width, height, format, BQ_LAYER_COUNT, usage))
{
+ if (CC_UNLIKELY(ATRACE_ENABLED())) {
+ if (buffer == nullptr) {
+ ATRACE_FORMAT_INSTANT("%s buffer reallocation: null", mConsumerName.c_str());
+ } else {
+ ATRACE_FORMAT_INSTANT("%s buffer reallocation actual %dx%d format:%d "
+ "layerCount:%d "
+ "usage:%d requested: %dx%d format:%d layerCount:%d "
+ "usage:%d ",
+ mConsumerName.c_str(), width, height, format,
+ BQ_LAYER_COUNT, usage, buffer->getWidth(),
+ buffer->getHeight(), buffer->getPixelFormat(),
+ buffer->getLayerCount(), buffer->getUsage());
+ }
+ }
mSlots[found].mAcquireCalled = false;
mSlots[found].mGraphicBuffer = nullptr;
mSlots[found].mRequestBufferCalled = false;
diff --git a/libs/gui/Choreographer.cpp b/libs/gui/Choreographer.cpp
new file mode 100644
index 0000000000..46fb068dee
--- /dev/null
+++ b/libs/gui/Choreographer.cpp
@@ -0,0 +1,397 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+// #define LOG_NDEBUG 0
+#define ATRACE_TAG ATRACE_TAG_GRAPHICS
+
+#include <gui/Choreographer.h>
+#include <gui/TraceUtils.h>
+#include <jni.h>
+
+#undef LOG_TAG
+#define LOG_TAG "AChoreographer"
+
+namespace {
+struct {
+ // Global JVM that is provided by zygote
+ JavaVM* jvm = nullptr;
+ struct {
+ jclass clazz;
+ jmethodID getInstance;
+ jmethodID registerNativeChoreographerForRefreshRateCallbacks;
+ jmethodID unregisterNativeChoreographerForRefreshRateCallbacks;
+ } displayManagerGlobal;
+} gJni;
+
+// Gets the JNIEnv* for this thread, and performs one-off initialization if we
+// have never retrieved a JNIEnv* pointer before.
+JNIEnv* getJniEnv() {
+ if (gJni.jvm == nullptr) {
+ ALOGW("AChoreographer: No JVM provided!");
+ return nullptr;
+ }
+
+ JNIEnv* env = nullptr;
+ if (gJni.jvm->GetEnv((void**)&env, JNI_VERSION_1_4) != JNI_OK) {
+ ALOGD("Attaching thread to JVM for AChoreographer");
+ JavaVMAttachArgs args = {JNI_VERSION_1_4, "AChoreographer_env", NULL};
+ jint attachResult = gJni.jvm->AttachCurrentThreadAsDaemon(&env, (void*)&args);
+ if (attachResult != JNI_OK) {
+ ALOGE("Unable to attach thread. Error: %d", attachResult);
+ return nullptr;
+ }
+ }
+ if (env == nullptr) {
+ ALOGW("AChoreographer: No JNI env available!");
+ }
+ return env;
+}
+
+inline const char* toString(bool value) {
+ return value ? "true" : "false";
+}
+} // namespace
+
+namespace android {
+
+Choreographer::Context Choreographer::gChoreographers;
+
+static thread_local Choreographer* gChoreographer;
+
+void Choreographer::initJVM(JNIEnv* env) {
+ env->GetJavaVM(&gJni.jvm);
+ // Now we need to find the java classes.
+ jclass dmgClass = env->FindClass("android/hardware/display/DisplayManagerGlobal");
+ gJni.displayManagerGlobal.clazz = static_cast<jclass>(env->NewGlobalRef(dmgClass));
+ gJni.displayManagerGlobal.getInstance =
+ env->GetStaticMethodID(dmgClass, "getInstance",
+ "()Landroid/hardware/display/DisplayManagerGlobal;");
+ gJni.displayManagerGlobal.registerNativeChoreographerForRefreshRateCallbacks =
+ env->GetMethodID(dmgClass, "registerNativeChoreographerForRefreshRateCallbacks", "()V");
+ gJni.displayManagerGlobal.unregisterNativeChoreographerForRefreshRateCallbacks =
+ env->GetMethodID(dmgClass, "unregisterNativeChoreographerForRefreshRateCallbacks",
+ "()V");
+}
+
+Choreographer* Choreographer::getForThread() {
+ if (gChoreographer == nullptr) {
+ sp<Looper> looper = Looper::getForThread();
+ if (!looper.get()) {
+ ALOGW("No looper prepared for thread");
+ return nullptr;
+ }
+ gChoreographer = new Choreographer(looper);
+ status_t result = gChoreographer->initialize();
+ if (result != OK) {
+ ALOGW("Failed to initialize");
+ return nullptr;
+ }
+ }
+ return gChoreographer;
+}
+
+Choreographer::Choreographer(const sp<Looper>& looper, const sp<IBinder>& layerHandle)
+ : DisplayEventDispatcher(looper, gui::ISurfaceComposer::VsyncSource::eVsyncSourceApp, {},
+ layerHandle),
+ mLooper(looper),
+ mThreadId(std::this_thread::get_id()) {
+ std::lock_guard<std::mutex> _l(gChoreographers.lock);
+ gChoreographers.ptrs.push_back(this);
+}
+
+Choreographer::~Choreographer() {
+ std::lock_guard<std::mutex> _l(gChoreographers.lock);
+ gChoreographers.ptrs.erase(std::remove_if(gChoreographers.ptrs.begin(),
+ gChoreographers.ptrs.end(),
+ [=](Choreographer* c) { return c == this; }),
+ gChoreographers.ptrs.end());
+ // Only poke DisplayManagerGlobal to unregister if we previously registered
+ // callbacks.
+ if (gChoreographers.ptrs.empty() && gChoreographers.registeredToDisplayManager) {
+ gChoreographers.registeredToDisplayManager = false;
+ JNIEnv* env = getJniEnv();
+ if (env == nullptr) {
+ ALOGW("JNI environment is unavailable, skipping choreographer cleanup");
+ return;
+ }
+ jobject dmg = env->CallStaticObjectMethod(gJni.displayManagerGlobal.clazz,
+ gJni.displayManagerGlobal.getInstance);
+ if (dmg == nullptr) {
+ ALOGW("DMS is not initialized yet, skipping choreographer cleanup");
+ } else {
+ env->CallVoidMethod(dmg,
+ gJni.displayManagerGlobal
+ .unregisterNativeChoreographerForRefreshRateCallbacks);
+ env->DeleteLocalRef(dmg);
+ }
+ }
+}
+
+void Choreographer::postFrameCallbackDelayed(AChoreographer_frameCallback cb,
+ AChoreographer_frameCallback64 cb64,
+ AChoreographer_vsyncCallback vsyncCallback, void* data,
+ nsecs_t delay) {
+ nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
+ FrameCallback callback{cb, cb64, vsyncCallback, data, now + delay};
+ {
+ std::lock_guard<std::mutex> _l{mLock};
+ mFrameCallbacks.push(callback);
+ }
+ if (callback.dueTime <= now) {
+ if (std::this_thread::get_id() != mThreadId) {
+ if (mLooper != nullptr) {
+ Message m{MSG_SCHEDULE_VSYNC};
+ mLooper->sendMessage(this, m);
+ } else {
+ scheduleVsync();
+ }
+ } else {
+ scheduleVsync();
+ }
+ } else {
+ if (mLooper != nullptr) {
+ Message m{MSG_SCHEDULE_CALLBACKS};
+ mLooper->sendMessageDelayed(delay, this, m);
+ } else {
+ scheduleCallbacks();
+ }
+ }
+}
+
+void Choreographer::registerRefreshRateCallback(AChoreographer_refreshRateCallback cb, void* data) {
+ std::lock_guard<std::mutex> _l{mLock};
+ for (const auto& callback : mRefreshRateCallbacks) {
+ // Don't re-add callbacks.
+ if (cb == callback.callback && data == callback.data) {
+ return;
+ }
+ }
+ mRefreshRateCallbacks.emplace_back(
+ RefreshRateCallback{.callback = cb, .data = data, .firstCallbackFired = false});
+ bool needsRegistration = false;
+ {
+ std::lock_guard<std::mutex> _l2(gChoreographers.lock);
+ needsRegistration = !gChoreographers.registeredToDisplayManager;
+ }
+ if (needsRegistration) {
+ JNIEnv* env = getJniEnv();
+ if (env == nullptr) {
+ ALOGW("JNI environment is unavailable, skipping registration");
+ return;
+ }
+ jobject dmg = env->CallStaticObjectMethod(gJni.displayManagerGlobal.clazz,
+ gJni.displayManagerGlobal.getInstance);
+ if (dmg == nullptr) {
+ ALOGW("DMS is not initialized yet: skipping registration");
+ return;
+ } else {
+ env->CallVoidMethod(dmg,
+ gJni.displayManagerGlobal
+ .registerNativeChoreographerForRefreshRateCallbacks,
+ reinterpret_cast<int64_t>(this));
+ env->DeleteLocalRef(dmg);
+ {
+ std::lock_guard<std::mutex> _l2(gChoreographers.lock);
+ gChoreographers.registeredToDisplayManager = true;
+ }
+ }
+ } else {
+ scheduleLatestConfigRequest();
+ }
+}
+
+void Choreographer::unregisterRefreshRateCallback(AChoreographer_refreshRateCallback cb,
+ void* data) {
+ std::lock_guard<std::mutex> _l{mLock};
+ mRefreshRateCallbacks.erase(std::remove_if(mRefreshRateCallbacks.begin(),
+ mRefreshRateCallbacks.end(),
+ [&](const RefreshRateCallback& callback) {
+ return cb == callback.callback &&
+ data == callback.data;
+ }),
+ mRefreshRateCallbacks.end());
+}
+
+void Choreographer::scheduleLatestConfigRequest() {
+ if (mLooper != nullptr) {
+ Message m{MSG_HANDLE_REFRESH_RATE_UPDATES};
+ mLooper->sendMessage(this, m);
+ } else {
+ // If the looper thread is detached from Choreographer, then refresh rate
+ // changes will be handled in AChoreographer_handlePendingEvents, so we
+ // need to wake up the looper thread by writing to the write-end of the
+ // socket the looper is listening on.
+ // Fortunately, these events are small so sending packets across the
+ // socket should be atomic across processes.
+ DisplayEventReceiver::Event event;
+ event.header =
+ DisplayEventReceiver::Event::Header{DisplayEventReceiver::DISPLAY_EVENT_NULL,
+ PhysicalDisplayId::fromPort(0), systemTime()};
+ injectEvent(event);
+ }
+}
+
+void Choreographer::scheduleCallbacks() {
+ const nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t dueTime;
+ {
+ std::lock_guard<std::mutex> _l{mLock};
+ // If there are no pending callbacks then don't schedule a vsync
+ if (mFrameCallbacks.empty()) {
+ return;
+ }
+ dueTime = mFrameCallbacks.top().dueTime;
+ }
+
+ if (dueTime <= now) {
+ ALOGV("choreographer %p ~ scheduling vsync", this);
+ scheduleVsync();
+ return;
+ }
+}
+
+void Choreographer::handleRefreshRateUpdates() {
+ std::vector<RefreshRateCallback> callbacks{};
+ const nsecs_t pendingPeriod = gChoreographers.mLastKnownVsync.load();
+ const nsecs_t lastPeriod = mLatestVsyncPeriod;
+ if (pendingPeriod > 0) {
+ mLatestVsyncPeriod = pendingPeriod;
+ }
+ {
+ std::lock_guard<std::mutex> _l{mLock};
+ for (auto& cb : mRefreshRateCallbacks) {
+ callbacks.push_back(cb);
+ cb.firstCallbackFired = true;
+ }
+ }
+
+ for (auto& cb : callbacks) {
+ if (!cb.firstCallbackFired || (pendingPeriod > 0 && pendingPeriod != lastPeriod)) {
+ cb.callback(pendingPeriod, cb.data);
+ }
+ }
+}
+
+void Choreographer::dispatchVsync(nsecs_t timestamp, PhysicalDisplayId, uint32_t,
+ VsyncEventData vsyncEventData) {
+ std::vector<FrameCallback> callbacks{};
+ {
+ std::lock_guard<std::mutex> _l{mLock};
+ nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
+ while (!mFrameCallbacks.empty() && mFrameCallbacks.top().dueTime < now) {
+ callbacks.push_back(mFrameCallbacks.top());
+ mFrameCallbacks.pop();
+ }
+ }
+ mLastVsyncEventData = vsyncEventData;
+ for (const auto& cb : callbacks) {
+ if (cb.vsyncCallback != nullptr) {
+ ATRACE_FORMAT("AChoreographer_vsyncCallback %" PRId64,
+ vsyncEventData.preferredVsyncId());
+ const ChoreographerFrameCallbackDataImpl frameCallbackData =
+ createFrameCallbackData(timestamp);
+ registerStartTime();
+ mInCallback = true;
+ cb.vsyncCallback(reinterpret_cast<const AChoreographerFrameCallbackData*>(
+ &frameCallbackData),
+ cb.data);
+ mInCallback = false;
+ } else if (cb.callback64 != nullptr) {
+ ATRACE_FORMAT("AChoreographer_frameCallback64");
+ cb.callback64(timestamp, cb.data);
+ } else if (cb.callback != nullptr) {
+ ATRACE_FORMAT("AChoreographer_frameCallback");
+ cb.callback(timestamp, cb.data);
+ }
+ }
+}
+
+void Choreographer::dispatchHotplug(nsecs_t, PhysicalDisplayId displayId, bool connected) {
+ ALOGV("choreographer %p ~ received hotplug event (displayId=%s, connected=%s), ignoring.", this,
+ to_string(displayId).c_str(), toString(connected));
+}
+
+void Choreographer::dispatchModeChanged(nsecs_t, PhysicalDisplayId, int32_t, nsecs_t) {
+ LOG_ALWAYS_FATAL("dispatchModeChanged was called but was never registered");
+}
+
+void Choreographer::dispatchFrameRateOverrides(nsecs_t, PhysicalDisplayId,
+ std::vector<FrameRateOverride>) {
+ LOG_ALWAYS_FATAL("dispatchFrameRateOverrides was called but was never registered");
+}
+
+void Choreographer::dispatchNullEvent(nsecs_t, PhysicalDisplayId) {
+ ALOGV("choreographer %p ~ received null event.", this);
+ handleRefreshRateUpdates();
+}
+
+void Choreographer::handleMessage(const Message& message) {
+ switch (message.what) {
+ case MSG_SCHEDULE_CALLBACKS:
+ scheduleCallbacks();
+ break;
+ case MSG_SCHEDULE_VSYNC:
+ scheduleVsync();
+ break;
+ case MSG_HANDLE_REFRESH_RATE_UPDATES:
+ handleRefreshRateUpdates();
+ break;
+ }
+}
+
+int64_t Choreographer::getFrameInterval() const {
+ return mLastVsyncEventData.frameInterval;
+}
+
+bool Choreographer::inCallback() const {
+ return mInCallback;
+}
+
+ChoreographerFrameCallbackDataImpl Choreographer::createFrameCallbackData(nsecs_t timestamp) const {
+ return {.frameTimeNanos = timestamp,
+ .vsyncEventData = mLastVsyncEventData,
+ .choreographer = this};
+}
+
+void Choreographer::registerStartTime() const {
+ std::scoped_lock _l(gChoreographers.lock);
+ for (VsyncEventData::FrameTimeline frameTimeline : mLastVsyncEventData.frameTimelines) {
+ while (gChoreographers.startTimes.size() >= kMaxStartTimes) {
+ gChoreographers.startTimes.erase(gChoreographers.startTimes.begin());
+ }
+ gChoreographers.startTimes[frameTimeline.vsyncId] = systemTime(SYSTEM_TIME_MONOTONIC);
+ }
+}
+
+void Choreographer::signalRefreshRateCallbacks(nsecs_t vsyncPeriod) {
+ std::lock_guard<std::mutex> _l(gChoreographers.lock);
+ gChoreographers.mLastKnownVsync.store(vsyncPeriod);
+ for (auto c : gChoreographers.ptrs) {
+ c->scheduleLatestConfigRequest();
+ }
+}
+
+int64_t Choreographer::getStartTimeNanosForVsyncId(AVsyncId vsyncId) {
+ std::scoped_lock _l(gChoreographers.lock);
+ const auto iter = gChoreographers.startTimes.find(vsyncId);
+ if (iter == gChoreographers.startTimes.end()) {
+ ALOGW("Start time was not found for vsync id: %" PRId64, vsyncId);
+ return 0;
+ }
+ return iter->second;
+}
+
+} // namespace android \ No newline at end of file
diff --git a/libs/gui/CompositorTiming.cpp b/libs/gui/CompositorTiming.cpp
new file mode 100644
index 0000000000..50f7b252b6
--- /dev/null
+++ b/libs/gui/CompositorTiming.cpp
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "CompositorTiming"
+
+#include <cutils/compiler.h>
+#include <gui/CompositorTiming.h>
+#include <log/log.h>
+
+namespace android::gui {
+
+CompositorTiming::CompositorTiming(nsecs_t vsyncDeadline, nsecs_t vsyncPeriod, nsecs_t vsyncPhase,
+ nsecs_t presentLatency) {
+ if (CC_UNLIKELY(vsyncPeriod <= 0)) {
+ ALOGE("Invalid VSYNC period");
+ return;
+ }
+
+ const nsecs_t idealLatency = [=] {
+ // Modulo rounds toward 0 not INT64_MIN, so treat signs separately.
+ if (vsyncPhase < 0) return -vsyncPhase % vsyncPeriod;
+
+ const nsecs_t latency = (vsyncPeriod - vsyncPhase) % vsyncPeriod;
+ return latency > 0 ? latency : vsyncPeriod;
+ }();
+
+ // Snap the latency to a value that removes scheduling jitter from the composite and present
+ // times, which often have >1ms of jitter. Reducing jitter is important if an app attempts to
+ // extrapolate something like user input to an accurate present time. Snapping also allows an
+ // app to precisely calculate vsyncPhase with (presentLatency % interval).
+ const nsecs_t bias = vsyncPeriod / 2;
+ const nsecs_t extraVsyncs = (presentLatency - idealLatency + bias) / vsyncPeriod;
+ const nsecs_t snappedLatency =
+ extraVsyncs > 0 ? idealLatency + extraVsyncs * vsyncPeriod : idealLatency;
+
+ this->deadline = vsyncDeadline - idealLatency;
+ this->interval = vsyncPeriod;
+ this->presentLatency = snappedLatency;
+}
+
+} // namespace android::gui
diff --git a/libs/gui/DisplayEventDispatcher.cpp b/libs/gui/DisplayEventDispatcher.cpp
index dfdce20438..8a883770d8 100644
--- a/libs/gui/DisplayEventDispatcher.cpp
+++ b/libs/gui/DisplayEventDispatcher.cpp
@@ -35,11 +35,15 @@ static const size_t EVENT_BUFFER_SIZE = 100;
static constexpr nsecs_t WAITING_FOR_VSYNC_TIMEOUT = ms2ns(300);
-DisplayEventDispatcher::DisplayEventDispatcher(
- const sp<Looper>& looper, ISurfaceComposer::VsyncSource vsyncSource,
- ISurfaceComposer::EventRegistrationFlags eventRegistration)
- : mLooper(looper), mReceiver(vsyncSource, eventRegistration), mWaitingForVsync(false),
- mLastVsyncCount(0), mLastScheduleVsyncTime(0) {
+DisplayEventDispatcher::DisplayEventDispatcher(const sp<Looper>& looper,
+ gui::ISurfaceComposer::VsyncSource vsyncSource,
+ EventRegistrationFlags eventRegistration,
+ const sp<IBinder>& layerHandle)
+ : mLooper(looper),
+ mReceiver(vsyncSource, eventRegistration, layerHandle),
+ mWaitingForVsync(false),
+ mLastVsyncCount(0),
+ mLastScheduleVsyncTime(0) {
ALOGV("dispatcher %p ~ Initializing display event dispatcher.", this);
}
diff --git a/libs/gui/DisplayEventReceiver.cpp b/libs/gui/DisplayEventReceiver.cpp
index bfb77699c0..6849a95d1e 100644
--- a/libs/gui/DisplayEventReceiver.cpp
+++ b/libs/gui/DisplayEventReceiver.cpp
@@ -14,15 +14,16 @@
* limitations under the License.
*/
+#define LOG_TAG "DisplayEventReceiver"
+
#include <string.h>
#include <utils/Errors.h>
#include <gui/DisplayEventReceiver.h>
-#include <gui/ISurfaceComposer.h>
#include <gui/VsyncEventData.h>
-#include <private/gui/ComposerService.h>
+#include <private/gui/ComposerServiceAIDL.h>
#include <private/gui/BitTube.h>
@@ -32,21 +33,29 @@ namespace android {
// ---------------------------------------------------------------------------
-DisplayEventReceiver::DisplayEventReceiver(
- ISurfaceComposer::VsyncSource vsyncSource,
- ISurfaceComposer::EventRegistrationFlags eventRegistration) {
- sp<ISurfaceComposer> sf(ComposerService::getComposerService());
+DisplayEventReceiver::DisplayEventReceiver(gui::ISurfaceComposer::VsyncSource vsyncSource,
+ EventRegistrationFlags eventRegistration,
+ const sp<IBinder>& layerHandle) {
+ sp<gui::ISurfaceComposer> sf(ComposerServiceAIDL::getComposerService());
if (sf != nullptr) {
- mEventConnection = sf->createDisplayEventConnection(vsyncSource, eventRegistration);
- if (mEventConnection != nullptr) {
+ mEventConnection = nullptr;
+ binder::Status status =
+ sf->createDisplayEventConnection(vsyncSource,
+ static_cast<
+ gui::ISurfaceComposer::EventRegistration>(
+ eventRegistration.get()),
+ layerHandle, &mEventConnection);
+ if (status.isOk() && mEventConnection != nullptr) {
mDataChannel = std::make_unique<gui::BitTube>();
- const auto status = mEventConnection->stealReceiveChannel(mDataChannel.get());
+ status = mEventConnection->stealReceiveChannel(mDataChannel.get());
if (!status.isOk()) {
ALOGE("stealReceiveChannel failed: %s", status.toString8().c_str());
mInitError = std::make_optional<status_t>(status.transactionError());
mDataChannel.reset();
mEventConnection.clear();
}
+ } else {
+ ALOGE("DisplayEventConnection creation failed: status=%s", status.toString8().c_str());
}
}
}
diff --git a/libs/gui/DisplayInfo.cpp b/libs/gui/DisplayInfo.cpp
index 52d9540eeb..bd640df81e 100644
--- a/libs/gui/DisplayInfo.cpp
+++ b/libs/gui/DisplayInfo.cpp
@@ -20,8 +20,13 @@
#include <gui/DisplayInfo.h>
#include <private/gui/ParcelUtils.h>
+#include <android-base/stringprintf.h>
#include <log/log.h>
+#include <inttypes.h>
+
+#define INDENT " "
+
namespace android::gui {
// --- DisplayInfo ---
@@ -67,4 +72,17 @@ status_t DisplayInfo::writeToParcel(android::Parcel* parcel) const {
return OK;
}
+void DisplayInfo::dump(std::string& out, const char* prefix) const {
+ using android::base::StringAppendF;
+
+ out += prefix;
+ StringAppendF(&out, "DisplayViewport[id=%" PRId32 "]\n", displayId);
+ out += prefix;
+ StringAppendF(&out, INDENT "Width=%" PRId32 ", Height=%" PRId32 "\n", logicalWidth,
+ logicalHeight);
+ std::string transformPrefix(prefix);
+ transformPrefix.append(INDENT);
+ transform.dump(out, "Transform", transformPrefix.c_str());
+}
+
} // namespace android::gui
diff --git a/libs/gui/FenceMonitor.cpp b/libs/gui/FenceMonitor.cpp
new file mode 100644
index 0000000000..230c81a0b3
--- /dev/null
+++ b/libs/gui/FenceMonitor.cpp
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define ATRACE_TAG ATRACE_TAG_GRAPHICS
+
+#include <gui/FenceMonitor.h>
+#include <gui/TraceUtils.h>
+#include <log/log.h>
+
+#include <thread>
+
+namespace android::gui {
+
+FenceMonitor::FenceMonitor(const char* name) : mName(name), mFencesQueued(0), mFencesSignaled(0) {
+ std::thread thread(&FenceMonitor::loop, this);
+ pthread_setname_np(thread.native_handle(), mName);
+ thread.detach();
+}
+
+void FenceMonitor::queueFence(const sp<Fence>& fence) {
+ char message[64];
+
+ std::lock_guard<std::mutex> lock(mMutex);
+ if (fence->getSignalTime() != Fence::SIGNAL_TIME_PENDING) {
+ snprintf(message, sizeof(message), "%s fence %u has signaled", mName, mFencesQueued);
+ ATRACE_NAME(message);
+ // Need an increment on both to make the trace number correct.
+ mFencesQueued++;
+ mFencesSignaled++;
+ return;
+ }
+ snprintf(message, sizeof(message), "Trace %s fence %u", mName, mFencesQueued);
+ ATRACE_NAME(message);
+
+ mQueue.push_back(fence);
+ mCondition.notify_one();
+ mFencesQueued++;
+ ATRACE_INT(mName, int32_t(mQueue.size()));
+}
+
+void FenceMonitor::loop() {
+ while (true) {
+ threadLoop();
+ }
+}
+
+void FenceMonitor::threadLoop() {
+ sp<Fence> fence;
+ uint32_t fenceNum;
+ {
+ std::unique_lock<std::mutex> lock(mMutex);
+ while (mQueue.empty()) {
+ mCondition.wait(lock);
+ }
+ fence = mQueue[0];
+ fenceNum = mFencesSignaled;
+ }
+ {
+ char message[64];
+ snprintf(message, sizeof(message), "waiting for %s %u", mName, fenceNum);
+ ATRACE_NAME(message);
+
+ status_t result = fence->waitForever(message);
+ if (result != OK) {
+ ALOGE("Error waiting for fence: %d", result);
+ }
+ }
+ {
+ std::lock_guard<std::mutex> lock(mMutex);
+ mQueue.pop_front();
+ mFencesSignaled++;
+ ATRACE_INT(mName, int32_t(mQueue.size()));
+ }
+}
+
+} // namespace android::gui \ No newline at end of file
diff --git a/libs/gui/FrameTimelineInfo.cpp b/libs/gui/FrameTimelineInfo.cpp
deleted file mode 100644
index 3800b88ab0..0000000000
--- a/libs/gui/FrameTimelineInfo.cpp
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "FrameTimelineInfo"
-
-#include <inttypes.h>
-
-#include <android/os/IInputConstants.h>
-#include <gui/FrameTimelineInfo.h>
-#include <gui/LayerState.h>
-#include <private/gui/ParcelUtils.h>
-#include <utils/Errors.h>
-
-#include <cmath>
-
-using android::os::IInputConstants;
-
-namespace android {
-
-status_t FrameTimelineInfo::write(Parcel& output) const {
- SAFE_PARCEL(output.writeInt64, vsyncId);
- SAFE_PARCEL(output.writeInt32, inputEventId);
- SAFE_PARCEL(output.writeInt64, startTimeNanos);
- return NO_ERROR;
-}
-
-status_t FrameTimelineInfo::read(const Parcel& input) {
- SAFE_PARCEL(input.readInt64, &vsyncId);
- SAFE_PARCEL(input.readInt32, &inputEventId);
- SAFE_PARCEL(input.readInt64, &startTimeNanos);
- return NO_ERROR;
-}
-
-void FrameTimelineInfo::merge(const FrameTimelineInfo& other) {
- // When merging vsync Ids we take the oldest valid one
- if (vsyncId != INVALID_VSYNC_ID && other.vsyncId != INVALID_VSYNC_ID) {
- if (other.vsyncId > vsyncId) {
- vsyncId = other.vsyncId;
- inputEventId = other.inputEventId;
- startTimeNanos = other.startTimeNanos;
- }
- } else if (vsyncId == INVALID_VSYNC_ID) {
- vsyncId = other.vsyncId;
- inputEventId = other.inputEventId;
- startTimeNanos = other.startTimeNanos;
- }
-}
-
-void FrameTimelineInfo::clear() {
- vsyncId = INVALID_VSYNC_ID;
- inputEventId = IInputConstants::INVALID_INPUT_EVENT_ID;
- startTimeNanos = 0;
-}
-
-}; // namespace android
diff --git a/libs/gui/GLConsumerUtils.cpp b/libs/gui/GLConsumerUtils.cpp
index 7a06c3d801..a1c69e7d6d 100644
--- a/libs/gui/GLConsumerUtils.cpp
+++ b/libs/gui/GLConsumerUtils.cpp
@@ -27,6 +27,13 @@ namespace android {
void GLConsumer::computeTransformMatrix(float outTransform[16],
const sp<GraphicBuffer>& buf, const Rect& cropRect, uint32_t transform,
bool filtering) {
+ computeTransformMatrix(outTransform, buf->getWidth(), buf->getHeight(), buf->getPixelFormat(),
+ cropRect, transform, filtering);
+}
+
+void GLConsumer::computeTransformMatrix(float outTransform[16], float bufferWidth,
+ float bufferHeight, PixelFormat pixelFormat,
+ const Rect& cropRect, uint32_t transform, bool filtering) {
// Transform matrices
static const mat4 mtxFlipH(
-1, 0, 0, 0,
@@ -60,8 +67,6 @@ void GLConsumer::computeTransformMatrix(float outTransform[16],
if (!cropRect.isEmpty()) {
float tx = 0.0f, ty = 0.0f, sx = 1.0f, sy = 1.0f;
- float bufferWidth = buf->getWidth();
- float bufferHeight = buf->getHeight();
float shrinkAmount = 0.0f;
if (filtering) {
// In order to prevent bilinear sampling beyond the edge of the
@@ -70,7 +75,7 @@ void GLConsumer::computeTransformMatrix(float outTransform[16],
// off each end, but because the chroma channels of YUV420 images
// are subsampled we may need to shrink the crop region by a whole
// texel on each side.
- switch (buf->getPixelFormat()) {
+ switch (pixelFormat) {
case PIXEL_FORMAT_RGBA_8888:
case PIXEL_FORMAT_RGBX_8888:
case PIXEL_FORMAT_RGBA_FP16:
diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp
index 24d39fe86a..b526a6c92c 100644
--- a/libs/gui/ISurfaceComposer.cpp
+++ b/libs/gui/ISurfaceComposer.cpp
@@ -19,14 +19,11 @@
#include <android/gui/IDisplayEventConnection.h>
#include <android/gui/IRegionSamplingListener.h>
-#include <android/gui/ITransactionTraceListener.h>
#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
#include <binder/Parcel.h>
#include <gui/IGraphicBufferProducer.h>
#include <gui/ISurfaceComposer.h>
-#include <gui/ISurfaceComposerClient.h>
-#include <gui/LayerDebugInfo.h>
#include <gui/LayerState.h>
#include <private/gui/ParcelUtils.h>
#include <stdint.h>
@@ -37,7 +34,6 @@
#include <ui/DisplayState.h>
#include <ui/DynamicDisplayInfo.h>
#include <ui/HdrCapabilities.h>
-#include <ui/StaticDisplayInfo.h>
#include <utils/Log.h>
// ---------------------------------------------------------------------------
@@ -63,26 +59,17 @@ public:
virtual ~BpSurfaceComposer();
- virtual sp<ISurfaceComposerClient> createConnection()
- {
- Parcel data, reply;
- data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
- remote()->transact(BnSurfaceComposer::CREATE_CONNECTION, data, &reply);
- return interface_cast<ISurfaceComposerClient>(reply.readStrongBinder());
- }
-
- status_t setTransactionState(const FrameTimelineInfo& frameTimelineInfo,
- const Vector<ComposerState>& state,
- const Vector<DisplayState>& displays, uint32_t flags,
- const sp<IBinder>& applyToken, const InputWindowCommands& commands,
- int64_t desiredPresentTime, bool isAutoTimestamp,
- const client_cache_t& uncacheBuffer, bool hasListenerCallbacks,
- const std::vector<ListenerCallbacks>& listenerCallbacks,
- uint64_t transactionId) override {
+ status_t setTransactionState(
+ const FrameTimelineInfo& frameTimelineInfo, Vector<ComposerState>& state,
+ const Vector<DisplayState>& displays, uint32_t flags, const sp<IBinder>& applyToken,
+ InputWindowCommands commands, int64_t desiredPresentTime, bool isAutoTimestamp,
+ const std::vector<client_cache_t>& uncacheBuffers, bool hasListenerCallbacks,
+ const std::vector<ListenerCallbacks>& listenerCallbacks, uint64_t transactionId,
+ const std::vector<uint64_t>& mergedTransactionIds) override {
Parcel data, reply;
data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
- SAFE_PARCEL(frameTimelineInfo.write, data);
+ frameTimelineInfo.writeToParcel(&data);
SAFE_PARCEL(data.writeUint32, static_cast<uint32_t>(state.size()));
for (const auto& s : state) {
@@ -99,8 +86,11 @@ public:
SAFE_PARCEL(commands.write, data);
SAFE_PARCEL(data.writeInt64, desiredPresentTime);
SAFE_PARCEL(data.writeBool, isAutoTimestamp);
- SAFE_PARCEL(data.writeStrongBinder, uncacheBuffer.token.promote());
- SAFE_PARCEL(data.writeUint64, uncacheBuffer.id);
+ SAFE_PARCEL(data.writeUint32, static_cast<uint32_t>(uncacheBuffers.size()));
+ for (const client_cache_t& uncacheBuffer : uncacheBuffers) {
+ SAFE_PARCEL(data.writeStrongBinder, uncacheBuffer.token.promote());
+ SAFE_PARCEL(data.writeUint64, uncacheBuffer.id);
+ }
SAFE_PARCEL(data.writeBool, hasListenerCallbacks);
SAFE_PARCEL(data.writeVectorSize, listenerCallbacks);
@@ -111,6 +101,11 @@ public:
SAFE_PARCEL(data.writeUint64, transactionId);
+ SAFE_PARCEL(data.writeUint32, static_cast<uint32_t>(mergedTransactionIds.size()));
+ for (auto mergedTransactionId : mergedTransactionIds) {
+ SAFE_PARCEL(data.writeUint64, mergedTransactionId);
+ }
+
if (flags & ISurfaceComposer::eOneWay) {
return remote()->transact(BnSurfaceComposer::SET_TRANSACTION_STATE,
data, &reply, IBinder::FLAG_ONEWAY);
@@ -119,905 +114,6 @@ public:
data, &reply);
}
}
-
- void bootFinished() override {
- Parcel data, reply;
- data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
- remote()->transact(BnSurfaceComposer::BOOT_FINISHED, data, &reply);
- }
-
- bool authenticateSurfaceTexture(
- const sp<IGraphicBufferProducer>& bufferProducer) const override {
- Parcel data, reply;
- int err = NO_ERROR;
- err = data.writeInterfaceToken(
- ISurfaceComposer::getInterfaceDescriptor());
- if (err != NO_ERROR) {
- ALOGE("ISurfaceComposer::authenticateSurfaceTexture: error writing "
- "interface descriptor: %s (%d)", strerror(-err), -err);
- return false;
- }
- err = data.writeStrongBinder(IInterface::asBinder(bufferProducer));
- if (err != NO_ERROR) {
- ALOGE("ISurfaceComposer::authenticateSurfaceTexture: error writing "
- "strong binder to parcel: %s (%d)", strerror(-err), -err);
- return false;
- }
- err = remote()->transact(BnSurfaceComposer::AUTHENTICATE_SURFACE, data,
- &reply);
- if (err != NO_ERROR) {
- ALOGE("ISurfaceComposer::authenticateSurfaceTexture: error "
- "performing transaction: %s (%d)", strerror(-err), -err);
- return false;
- }
- int32_t result = 0;
- err = reply.readInt32(&result);
- if (err != NO_ERROR) {
- ALOGE("ISurfaceComposer::authenticateSurfaceTexture: error "
- "retrieving result: %s (%d)", strerror(-err), -err);
- return false;
- }
- return result != 0;
- }
-
- status_t getSupportedFrameTimestamps(std::vector<FrameEvent>* outSupported) const override {
- if (!outSupported) {
- return UNEXPECTED_NULL;
- }
- outSupported->clear();
-
- Parcel data, reply;
-
- status_t err = data.writeInterfaceToken(
- ISurfaceComposer::getInterfaceDescriptor());
- if (err != NO_ERROR) {
- return err;
- }
-
- err = remote()->transact(
- BnSurfaceComposer::GET_SUPPORTED_FRAME_TIMESTAMPS,
- data, &reply);
- if (err != NO_ERROR) {
- return err;
- }
-
- int32_t result = 0;
- err = reply.readInt32(&result);
- if (err != NO_ERROR) {
- return err;
- }
- if (result != NO_ERROR) {
- return result;
- }
-
- std::vector<int32_t> supported;
- err = reply.readInt32Vector(&supported);
- if (err != NO_ERROR) {
- return err;
- }
-
- outSupported->reserve(supported.size());
- for (int32_t s : supported) {
- outSupported->push_back(static_cast<FrameEvent>(s));
- }
- return NO_ERROR;
- }
-
- sp<IDisplayEventConnection> createDisplayEventConnection(
- VsyncSource vsyncSource, EventRegistrationFlags eventRegistration) override {
- Parcel data, reply;
- sp<IDisplayEventConnection> result;
- int err = data.writeInterfaceToken(
- ISurfaceComposer::getInterfaceDescriptor());
- if (err != NO_ERROR) {
- return result;
- }
- data.writeInt32(static_cast<int32_t>(vsyncSource));
- data.writeUint32(eventRegistration.get());
- err = remote()->transact(
- BnSurfaceComposer::CREATE_DISPLAY_EVENT_CONNECTION,
- data, &reply);
- if (err != NO_ERROR) {
- ALOGE("ISurfaceComposer::createDisplayEventConnection: error performing "
- "transaction: %s (%d)", strerror(-err), -err);
- return result;
- }
- result = interface_cast<IDisplayEventConnection>(reply.readStrongBinder());
- return result;
- }
-
- status_t getStaticDisplayInfo(const sp<IBinder>& display,
- ui::StaticDisplayInfo* info) override {
- Parcel data, reply;
- data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
- data.writeStrongBinder(display);
- remote()->transact(BnSurfaceComposer::GET_STATIC_DISPLAY_INFO, data, &reply);
- const status_t result = reply.readInt32();
- if (result != NO_ERROR) return result;
- return reply.read(*info);
- }
-
- status_t getDynamicDisplayInfo(const sp<IBinder>& display,
- ui::DynamicDisplayInfo* info) override {
- Parcel data, reply;
- data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
- data.writeStrongBinder(display);
- remote()->transact(BnSurfaceComposer::GET_DYNAMIC_DISPLAY_INFO, data, &reply);
- const status_t result = reply.readInt32();
- if (result != NO_ERROR) return result;
- return reply.read(*info);
- }
-
- status_t getDisplayNativePrimaries(const sp<IBinder>& display,
- ui::DisplayPrimaries& primaries) override {
- Parcel data, reply;
- status_t result = data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
- if (result != NO_ERROR) {
- ALOGE("getDisplayNativePrimaries failed to writeInterfaceToken: %d", result);
- return result;
- }
- result = data.writeStrongBinder(display);
- if (result != NO_ERROR) {
- ALOGE("getDisplayNativePrimaries failed to writeStrongBinder: %d", result);
- return result;
- }
- result = remote()->transact(BnSurfaceComposer::GET_DISPLAY_NATIVE_PRIMARIES, data, &reply);
- if (result != NO_ERROR) {
- ALOGE("getDisplayNativePrimaries failed to transact: %d", result);
- return result;
- }
- result = reply.readInt32();
- if (result == NO_ERROR) {
- memcpy(&primaries, reply.readInplace(sizeof(ui::DisplayPrimaries)),
- sizeof(ui::DisplayPrimaries));
- }
- return result;
- }
-
- status_t setActiveColorMode(const sp<IBinder>& display, ColorMode colorMode) override {
- Parcel data, reply;
- status_t result = data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
- if (result != NO_ERROR) {
- ALOGE("setActiveColorMode failed to writeInterfaceToken: %d", result);
- return result;
- }
- result = data.writeStrongBinder(display);
- if (result != NO_ERROR) {
- ALOGE("setActiveColorMode failed to writeStrongBinder: %d", result);
- return result;
- }
- result = data.writeInt32(static_cast<int32_t>(colorMode));
- if (result != NO_ERROR) {
- ALOGE("setActiveColorMode failed to writeInt32: %d", result);
- return result;
- }
- result = remote()->transact(BnSurfaceComposer::SET_ACTIVE_COLOR_MODE, data, &reply);
- if (result != NO_ERROR) {
- ALOGE("setActiveColorMode failed to transact: %d", result);
- return result;
- }
- return static_cast<status_t>(reply.readInt32());
- }
-
- status_t setBootDisplayMode(const sp<IBinder>& display,
- ui::DisplayModeId displayModeId) override {
- Parcel data, reply;
- status_t result = data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
- if (result != NO_ERROR) {
- ALOGE("setBootDisplayMode failed to writeInterfaceToken: %d", result);
- return result;
- }
- result = data.writeStrongBinder(display);
- if (result != NO_ERROR) {
- ALOGE("setBootDisplayMode failed to writeStrongBinder: %d", result);
- return result;
- }
- result = data.writeInt32(displayModeId);
- if (result != NO_ERROR) {
- ALOGE("setBootDisplayMode failed to writeIint32: %d", result);
- return result;
- }
- result = remote()->transact(BnSurfaceComposer::SET_BOOT_DISPLAY_MODE, data, &reply);
- if (result != NO_ERROR) {
- ALOGE("setBootDisplayMode failed to transact: %d", result);
- }
- return result;
- }
-
- status_t clearAnimationFrameStats() override {
- Parcel data, reply;
- status_t result = data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
- if (result != NO_ERROR) {
- ALOGE("clearAnimationFrameStats failed to writeInterfaceToken: %d", result);
- return result;
- }
- result = remote()->transact(BnSurfaceComposer::CLEAR_ANIMATION_FRAME_STATS, data, &reply);
- if (result != NO_ERROR) {
- ALOGE("clearAnimationFrameStats failed to transact: %d", result);
- return result;
- }
- return reply.readInt32();
- }
-
- status_t getAnimationFrameStats(FrameStats* outStats) const override {
- Parcel data, reply;
- data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
- remote()->transact(BnSurfaceComposer::GET_ANIMATION_FRAME_STATS, data, &reply);
- reply.read(*outStats);
- return reply.readInt32();
- }
-
- virtual status_t overrideHdrTypes(const sp<IBinder>& display,
- const std::vector<ui::Hdr>& hdrTypes) {
- Parcel data, reply;
- SAFE_PARCEL(data.writeInterfaceToken, ISurfaceComposer::getInterfaceDescriptor());
- SAFE_PARCEL(data.writeStrongBinder, display);
-
- std::vector<int32_t> hdrTypesVector;
- for (ui::Hdr i : hdrTypes) {
- hdrTypesVector.push_back(static_cast<int32_t>(i));
- }
- SAFE_PARCEL(data.writeInt32Vector, hdrTypesVector);
-
- status_t result = remote()->transact(BnSurfaceComposer::OVERRIDE_HDR_TYPES, data, &reply);
- if (result != NO_ERROR) {
- ALOGE("overrideHdrTypes failed to transact: %d", result);
- return result;
- }
- return result;
- }
-
- status_t onPullAtom(const int32_t atomId, std::string* pulledData, bool* success) {
- Parcel data, reply;
- SAFE_PARCEL(data.writeInterfaceToken, ISurfaceComposer::getInterfaceDescriptor());
- SAFE_PARCEL(data.writeInt32, atomId);
-
- status_t err = remote()->transact(BnSurfaceComposer::ON_PULL_ATOM, data, &reply);
- if (err != NO_ERROR) {
- ALOGE("onPullAtom failed to transact: %d", err);
- return err;
- }
-
- int32_t size = 0;
- SAFE_PARCEL(reply.readInt32, &size);
- const void* dataPtr = reply.readInplace(size);
- if (dataPtr == nullptr) {
- return UNEXPECTED_NULL;
- }
- pulledData->assign((const char*)dataPtr, size);
- SAFE_PARCEL(reply.readBool, success);
- return NO_ERROR;
- }
-
- status_t enableVSyncInjections(bool enable) override {
- Parcel data, reply;
- status_t result = data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
- if (result != NO_ERROR) {
- ALOGE("enableVSyncInjections failed to writeInterfaceToken: %d", result);
- return result;
- }
- result = data.writeBool(enable);
- if (result != NO_ERROR) {
- ALOGE("enableVSyncInjections failed to writeBool: %d", result);
- return result;
- }
- result = remote()->transact(BnSurfaceComposer::ENABLE_VSYNC_INJECTIONS, data, &reply,
- IBinder::FLAG_ONEWAY);
- if (result != NO_ERROR) {
- ALOGE("enableVSyncInjections failed to transact: %d", result);
- return result;
- }
- return result;
- }
-
- status_t injectVSync(nsecs_t when) override {
- Parcel data, reply;
- status_t result = data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
- if (result != NO_ERROR) {
- ALOGE("injectVSync failed to writeInterfaceToken: %d", result);
- return result;
- }
- result = data.writeInt64(when);
- if (result != NO_ERROR) {
- ALOGE("injectVSync failed to writeInt64: %d", result);
- return result;
- }
- result = remote()->transact(BnSurfaceComposer::INJECT_VSYNC, data, &reply,
- IBinder::FLAG_ONEWAY);
- if (result != NO_ERROR) {
- ALOGE("injectVSync failed to transact: %d", result);
- return result;
- }
- return result;
- }
-
- status_t getLayerDebugInfo(std::vector<LayerDebugInfo>* outLayers) override {
- if (!outLayers) {
- return UNEXPECTED_NULL;
- }
-
- Parcel data, reply;
-
- status_t err = data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
- if (err != NO_ERROR) {
- return err;
- }
-
- err = remote()->transact(BnSurfaceComposer::GET_LAYER_DEBUG_INFO, data, &reply);
- if (err != NO_ERROR) {
- return err;
- }
-
- int32_t result = 0;
- err = reply.readInt32(&result);
- if (err != NO_ERROR) {
- return err;
- }
- if (result != NO_ERROR) {
- return result;
- }
-
- outLayers->clear();
- return reply.readParcelableVector(outLayers);
- }
-
- status_t getCompositionPreference(ui::Dataspace* defaultDataspace,
- ui::PixelFormat* defaultPixelFormat,
- ui::Dataspace* wideColorGamutDataspace,
- ui::PixelFormat* wideColorGamutPixelFormat) const override {
- Parcel data, reply;
- status_t error = data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
- if (error != NO_ERROR) {
- return error;
- }
- error = remote()->transact(BnSurfaceComposer::GET_COMPOSITION_PREFERENCE, data, &reply);
- if (error != NO_ERROR) {
- return error;
- }
- error = static_cast<status_t>(reply.readInt32());
- if (error == NO_ERROR) {
- *defaultDataspace = static_cast<ui::Dataspace>(reply.readInt32());
- *defaultPixelFormat = static_cast<ui::PixelFormat>(reply.readInt32());
- *wideColorGamutDataspace = static_cast<ui::Dataspace>(reply.readInt32());
- *wideColorGamutPixelFormat = static_cast<ui::PixelFormat>(reply.readInt32());
- }
- return error;
- }
-
- status_t getColorManagement(bool* outGetColorManagement) const override {
- Parcel data, reply;
- data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
- remote()->transact(BnSurfaceComposer::GET_COLOR_MANAGEMENT, data, &reply);
- bool result;
- status_t err = reply.readBool(&result);
- if (err == NO_ERROR) {
- *outGetColorManagement = result;
- }
- return err;
- }
-
- status_t getDisplayedContentSamplingAttributes(const sp<IBinder>& display,
- ui::PixelFormat* outFormat,
- ui::Dataspace* outDataspace,
- uint8_t* outComponentMask) const override {
- if (!outFormat || !outDataspace || !outComponentMask) return BAD_VALUE;
- Parcel data, reply;
- data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
- data.writeStrongBinder(display);
-
- status_t error =
- remote()->transact(BnSurfaceComposer::GET_DISPLAYED_CONTENT_SAMPLING_ATTRIBUTES,
- data, &reply);
- if (error != NO_ERROR) {
- return error;
- }
-
- uint32_t value = 0;
- error = reply.readUint32(&value);
- if (error != NO_ERROR) {
- return error;
- }
- *outFormat = static_cast<ui::PixelFormat>(value);
-
- error = reply.readUint32(&value);
- if (error != NO_ERROR) {
- return error;
- }
- *outDataspace = static_cast<ui::Dataspace>(value);
-
- error = reply.readUint32(&value);
- if (error != NO_ERROR) {
- return error;
- }
- *outComponentMask = static_cast<uint8_t>(value);
- return error;
- }
-
- status_t setDisplayContentSamplingEnabled(const sp<IBinder>& display, bool enable,
- uint8_t componentMask, uint64_t maxFrames) override {
- Parcel data, reply;
- data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
- data.writeStrongBinder(display);
- data.writeBool(enable);
- data.writeByte(static_cast<int8_t>(componentMask));
- data.writeUint64(maxFrames);
- status_t result =
- remote()->transact(BnSurfaceComposer::SET_DISPLAY_CONTENT_SAMPLING_ENABLED, data,
- &reply);
- return result;
- }
-
- status_t getDisplayedContentSample(const sp<IBinder>& display, uint64_t maxFrames,
- uint64_t timestamp,
- DisplayedFrameStats* outStats) const override {
- if (!outStats) return BAD_VALUE;
-
- Parcel data, reply;
- data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
- data.writeStrongBinder(display);
- data.writeUint64(maxFrames);
- data.writeUint64(timestamp);
-
- status_t result =
- remote()->transact(BnSurfaceComposer::GET_DISPLAYED_CONTENT_SAMPLE, data, &reply);
-
- if (result != NO_ERROR) {
- return result;
- }
-
- result = reply.readUint64(&outStats->numFrames);
- if (result != NO_ERROR) {
- return result;
- }
-
- result = reply.readUint64Vector(&outStats->component_0_sample);
- if (result != NO_ERROR) {
- return result;
- }
- result = reply.readUint64Vector(&outStats->component_1_sample);
- if (result != NO_ERROR) {
- return result;
- }
- result = reply.readUint64Vector(&outStats->component_2_sample);
- if (result != NO_ERROR) {
- return result;
- }
- result = reply.readUint64Vector(&outStats->component_3_sample);
- return result;
- }
-
- status_t getProtectedContentSupport(bool* outSupported) const override {
- Parcel data, reply;
- data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
- status_t error =
- remote()->transact(BnSurfaceComposer::GET_PROTECTED_CONTENT_SUPPORT, data, &reply);
- if (error != NO_ERROR) {
- return error;
- }
- error = reply.readBool(outSupported);
- return error;
- }
-
- status_t addRegionSamplingListener(const Rect& samplingArea, const sp<IBinder>& stopLayerHandle,
- const sp<IRegionSamplingListener>& listener) override {
- Parcel data, reply;
- status_t error = data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
- if (error != NO_ERROR) {
- ALOGE("addRegionSamplingListener: Failed to write interface token");
- return error;
- }
- error = data.write(samplingArea);
- if (error != NO_ERROR) {
- ALOGE("addRegionSamplingListener: Failed to write sampling area");
- return error;
- }
- error = data.writeStrongBinder(stopLayerHandle);
- if (error != NO_ERROR) {
- ALOGE("addRegionSamplingListener: Failed to write stop layer handle");
- return error;
- }
- error = data.writeStrongBinder(IInterface::asBinder(listener));
- if (error != NO_ERROR) {
- ALOGE("addRegionSamplingListener: Failed to write listener");
- return error;
- }
- error = remote()->transact(BnSurfaceComposer::ADD_REGION_SAMPLING_LISTENER, data, &reply);
- if (error != NO_ERROR) {
- ALOGE("addRegionSamplingListener: Failed to transact");
- }
- return error;
- }
-
- status_t removeRegionSamplingListener(const sp<IRegionSamplingListener>& listener) override {
- Parcel data, reply;
- status_t error = data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
- if (error != NO_ERROR) {
- ALOGE("removeRegionSamplingListener: Failed to write interface token");
- return error;
- }
- error = data.writeStrongBinder(IInterface::asBinder(listener));
- if (error != NO_ERROR) {
- ALOGE("removeRegionSamplingListener: Failed to write listener");
- return error;
- }
- error = remote()->transact(BnSurfaceComposer::REMOVE_REGION_SAMPLING_LISTENER, data,
- &reply);
- if (error != NO_ERROR) {
- ALOGE("removeRegionSamplingListener: Failed to transact");
- }
- return error;
- }
-
- virtual status_t addFpsListener(int32_t taskId, const sp<gui::IFpsListener>& listener) {
- Parcel data, reply;
- SAFE_PARCEL(data.writeInterfaceToken, ISurfaceComposer::getInterfaceDescriptor());
- SAFE_PARCEL(data.writeInt32, taskId);
- SAFE_PARCEL(data.writeStrongBinder, IInterface::asBinder(listener));
- const status_t error =
- remote()->transact(BnSurfaceComposer::ADD_FPS_LISTENER, data, &reply);
- if (error != OK) {
- ALOGE("addFpsListener: Failed to transact");
- }
- return error;
- }
-
- virtual status_t removeFpsListener(const sp<gui::IFpsListener>& listener) {
- Parcel data, reply;
- SAFE_PARCEL(data.writeInterfaceToken, ISurfaceComposer::getInterfaceDescriptor());
- SAFE_PARCEL(data.writeStrongBinder, IInterface::asBinder(listener));
-
- const status_t error =
- remote()->transact(BnSurfaceComposer::REMOVE_FPS_LISTENER, data, &reply);
- if (error != OK) {
- ALOGE("removeFpsListener: Failed to transact");
- }
- return error;
- }
-
- virtual status_t addTunnelModeEnabledListener(
- const sp<gui::ITunnelModeEnabledListener>& listener) {
- Parcel data, reply;
- SAFE_PARCEL(data.writeInterfaceToken, ISurfaceComposer::getInterfaceDescriptor());
- SAFE_PARCEL(data.writeStrongBinder, IInterface::asBinder(listener));
-
- const status_t error =
- remote()->transact(BnSurfaceComposer::ADD_TUNNEL_MODE_ENABLED_LISTENER, data,
- &reply);
- if (error != NO_ERROR) {
- ALOGE("addTunnelModeEnabledListener: Failed to transact");
- }
- return error;
- }
-
- virtual status_t removeTunnelModeEnabledListener(
- const sp<gui::ITunnelModeEnabledListener>& listener) {
- Parcel data, reply;
- SAFE_PARCEL(data.writeInterfaceToken, ISurfaceComposer::getInterfaceDescriptor());
- SAFE_PARCEL(data.writeStrongBinder, IInterface::asBinder(listener));
-
- const status_t error =
- remote()->transact(BnSurfaceComposer::REMOVE_TUNNEL_MODE_ENABLED_LISTENER, data,
- &reply);
- if (error != NO_ERROR) {
- ALOGE("removeTunnelModeEnabledListener: Failed to transact");
- }
- return error;
- }
-
- status_t setDesiredDisplayModeSpecs(const sp<IBinder>& displayToken,
- ui::DisplayModeId defaultMode, bool allowGroupSwitching,
- float primaryRefreshRateMin, float primaryRefreshRateMax,
- float appRequestRefreshRateMin,
- float appRequestRefreshRateMax) override {
- Parcel data, reply;
- status_t result = data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
- if (result != NO_ERROR) {
- ALOGE("setDesiredDisplayModeSpecs: failed to writeInterfaceToken: %d", result);
- return result;
- }
- result = data.writeStrongBinder(displayToken);
- if (result != NO_ERROR) {
- ALOGE("setDesiredDisplayModeSpecs: failed to write display token: %d", result);
- return result;
- }
- result = data.writeInt32(defaultMode);
- if (result != NO_ERROR) {
- ALOGE("setDesiredDisplayModeSpecs failed to write defaultMode: %d", result);
- return result;
- }
- result = data.writeBool(allowGroupSwitching);
- if (result != NO_ERROR) {
- ALOGE("setDesiredDisplayModeSpecs failed to write allowGroupSwitching: %d", result);
- return result;
- }
- result = data.writeFloat(primaryRefreshRateMin);
- if (result != NO_ERROR) {
- ALOGE("setDesiredDisplayModeSpecs failed to write primaryRefreshRateMin: %d", result);
- return result;
- }
- result = data.writeFloat(primaryRefreshRateMax);
- if (result != NO_ERROR) {
- ALOGE("setDesiredDisplayModeSpecs failed to write primaryRefreshRateMax: %d", result);
- return result;
- }
- result = data.writeFloat(appRequestRefreshRateMin);
- if (result != NO_ERROR) {
- ALOGE("setDesiredDisplayModeSpecs failed to write appRequestRefreshRateMin: %d",
- result);
- return result;
- }
- result = data.writeFloat(appRequestRefreshRateMax);
- if (result != NO_ERROR) {
- ALOGE("setDesiredDisplayModeSpecs failed to write appRequestRefreshRateMax: %d",
- result);
- return result;
- }
-
- result =
- remote()->transact(BnSurfaceComposer::SET_DESIRED_DISPLAY_MODE_SPECS, data, &reply);
- if (result != NO_ERROR) {
- ALOGE("setDesiredDisplayModeSpecs failed to transact: %d", result);
- return result;
- }
- return reply.readInt32();
- }
-
- status_t getDesiredDisplayModeSpecs(const sp<IBinder>& displayToken,
- ui::DisplayModeId* outDefaultMode,
- bool* outAllowGroupSwitching,
- float* outPrimaryRefreshRateMin,
- float* outPrimaryRefreshRateMax,
- float* outAppRequestRefreshRateMin,
- float* outAppRequestRefreshRateMax) override {
- if (!outDefaultMode || !outAllowGroupSwitching || !outPrimaryRefreshRateMin ||
- !outPrimaryRefreshRateMax || !outAppRequestRefreshRateMin ||
- !outAppRequestRefreshRateMax) {
- return BAD_VALUE;
- }
- Parcel data, reply;
- status_t result = data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
- if (result != NO_ERROR) {
- ALOGE("getDesiredDisplayModeSpecs failed to writeInterfaceToken: %d", result);
- return result;
- }
- result = data.writeStrongBinder(displayToken);
- if (result != NO_ERROR) {
- ALOGE("getDesiredDisplayModeSpecs failed to writeStrongBinder: %d", result);
- return result;
- }
- result =
- remote()->transact(BnSurfaceComposer::GET_DESIRED_DISPLAY_MODE_SPECS, data, &reply);
- if (result != NO_ERROR) {
- ALOGE("getDesiredDisplayModeSpecs failed to transact: %d", result);
- return result;
- }
-
- result = reply.readInt32(outDefaultMode);
- if (result != NO_ERROR) {
- ALOGE("getDesiredDisplayModeSpecs failed to read defaultMode: %d", result);
- return result;
- }
- if (*outDefaultMode < 0) {
- ALOGE("%s: defaultMode must be non-negative but it was %d", __func__, *outDefaultMode);
- return BAD_VALUE;
- }
-
- result = reply.readBool(outAllowGroupSwitching);
- if (result != NO_ERROR) {
- ALOGE("getDesiredDisplayModeSpecs failed to read allowGroupSwitching: %d", result);
- return result;
- }
- result = reply.readFloat(outPrimaryRefreshRateMin);
- if (result != NO_ERROR) {
- ALOGE("getDesiredDisplayModeSpecs failed to read primaryRefreshRateMin: %d", result);
- return result;
- }
- result = reply.readFloat(outPrimaryRefreshRateMax);
- if (result != NO_ERROR) {
- ALOGE("getDesiredDisplayModeSpecs failed to read primaryRefreshRateMax: %d", result);
- return result;
- }
- result = reply.readFloat(outAppRequestRefreshRateMin);
- if (result != NO_ERROR) {
- ALOGE("getDesiredDisplayModeSpecs failed to read appRequestRefreshRateMin: %d", result);
- return result;
- }
- result = reply.readFloat(outAppRequestRefreshRateMax);
- if (result != NO_ERROR) {
- ALOGE("getDesiredDisplayModeSpecs failed to read appRequestRefreshRateMax: %d", result);
- return result;
- }
- return reply.readInt32();
- }
-
- status_t setGlobalShadowSettings(const half4& ambientColor, const half4& spotColor,
- float lightPosY, float lightPosZ, float lightRadius) override {
- Parcel data, reply;
- status_t error = data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
- if (error != NO_ERROR) {
- ALOGE("setGlobalShadowSettings: failed to write interface token: %d", error);
- return error;
- }
-
- std::vector<float> shadowConfig = {ambientColor.r, ambientColor.g, ambientColor.b,
- ambientColor.a, spotColor.r, spotColor.g,
- spotColor.b, spotColor.a, lightPosY,
- lightPosZ, lightRadius};
-
- error = data.writeFloatVector(shadowConfig);
- if (error != NO_ERROR) {
- ALOGE("setGlobalShadowSettings: failed to write shadowConfig: %d", error);
- return error;
- }
-
- error = remote()->transact(BnSurfaceComposer::SET_GLOBAL_SHADOW_SETTINGS, data, &reply,
- IBinder::FLAG_ONEWAY);
- if (error != NO_ERROR) {
- ALOGE("setGlobalShadowSettings: failed to transact: %d", error);
- return error;
- }
- return NO_ERROR;
- }
-
- status_t getDisplayDecorationSupport(
- const sp<IBinder>& displayToken,
- std::optional<common::DisplayDecorationSupport>* outSupport) const override {
- Parcel data, reply;
- status_t error = data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
- if (error != NO_ERROR) {
- ALOGE("getDisplayDecorationSupport: failed to write interface token: %d", error);
- return error;
- }
- error = data.writeStrongBinder(displayToken);
- if (error != NO_ERROR) {
- ALOGE("getDisplayDecorationSupport: failed to write display token: %d", error);
- return error;
- }
- error = remote()->transact(BnSurfaceComposer::GET_DISPLAY_DECORATION_SUPPORT, data, &reply);
- if (error != NO_ERROR) {
- ALOGE("getDisplayDecorationSupport: failed to transact: %d", error);
- return error;
- }
- bool support;
- error = reply.readBool(&support);
- if (error != NO_ERROR) {
- ALOGE("getDisplayDecorationSupport: failed to read support: %d", error);
- return error;
- }
-
- if (support) {
- int32_t format, alphaInterpretation;
- error = reply.readInt32(&format);
- if (error != NO_ERROR) {
- ALOGE("getDisplayDecorationSupport: failed to read format: %d", error);
- return error;
- }
- error = reply.readInt32(&alphaInterpretation);
- if (error != NO_ERROR) {
- ALOGE("getDisplayDecorationSupport: failed to read alphaInterpretation: %d", error);
- return error;
- }
- outSupport->emplace();
- outSupport->value().format = static_cast<common::PixelFormat>(format);
- outSupport->value().alphaInterpretation =
- static_cast<common::AlphaInterpretation>(alphaInterpretation);
- } else {
- outSupport->reset();
- }
- return NO_ERROR;
- }
-
- status_t setFrameRate(const sp<IGraphicBufferProducer>& surface, float frameRate,
- int8_t compatibility, int8_t changeFrameRateStrategy) override {
- Parcel data, reply;
- SAFE_PARCEL(data.writeInterfaceToken, ISurfaceComposer::getInterfaceDescriptor());
- SAFE_PARCEL(data.writeStrongBinder, IInterface::asBinder(surface));
- SAFE_PARCEL(data.writeFloat, frameRate);
- SAFE_PARCEL(data.writeByte, compatibility);
- SAFE_PARCEL(data.writeByte, changeFrameRateStrategy);
-
- status_t err = remote()->transact(BnSurfaceComposer::SET_FRAME_RATE, data, &reply);
- if (err != NO_ERROR) {
- ALOGE("setFrameRate: failed to transact: %s (%d)", strerror(-err), err);
- return err;
- }
-
- return reply.readInt32();
- }
-
- status_t setFrameTimelineInfo(const sp<IGraphicBufferProducer>& surface,
- const FrameTimelineInfo& frameTimelineInfo) override {
- Parcel data, reply;
- status_t err = data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
- if (err != NO_ERROR) {
- ALOGE("%s: failed writing interface token: %s (%d)", __func__, strerror(-err), -err);
- return err;
- }
-
- err = data.writeStrongBinder(IInterface::asBinder(surface));
- if (err != NO_ERROR) {
- ALOGE("%s: failed writing strong binder: %s (%d)", __func__, strerror(-err), -err);
- return err;
- }
-
- SAFE_PARCEL(frameTimelineInfo.write, data);
-
- err = remote()->transact(BnSurfaceComposer::SET_FRAME_TIMELINE_INFO, data, &reply);
- if (err != NO_ERROR) {
- ALOGE("%s: failed to transact: %s (%d)", __func__, strerror(-err), err);
- return err;
- }
-
- return reply.readInt32();
- }
-
- status_t addTransactionTraceListener(
- const sp<gui::ITransactionTraceListener>& listener) override {
- Parcel data, reply;
- SAFE_PARCEL(data.writeInterfaceToken, ISurfaceComposer::getInterfaceDescriptor());
- SAFE_PARCEL(data.writeStrongBinder, IInterface::asBinder(listener));
-
- return remote()->transact(BnSurfaceComposer::ADD_TRANSACTION_TRACE_LISTENER, data, &reply);
- }
-
- /**
- * Get priority of the RenderEngine in surface flinger.
- */
- int getGPUContextPriority() override {
- Parcel data, reply;
- data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
- status_t err =
- remote()->transact(BnSurfaceComposer::GET_GPU_CONTEXT_PRIORITY, data, &reply);
- if (err != NO_ERROR) {
- ALOGE("getGPUContextPriority failed to read data: %s (%d)", strerror(-err), err);
- return 0;
- }
- return reply.readInt32();
- }
-
- status_t getMaxAcquiredBufferCount(int* buffers) const override {
- Parcel data, reply;
- data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
- status_t err =
- remote()->transact(BnSurfaceComposer::GET_MAX_ACQUIRED_BUFFER_COUNT, data, &reply);
- if (err != NO_ERROR) {
- ALOGE("getMaxAcquiredBufferCount failed to read data: %s (%d)", strerror(-err), err);
- return err;
- }
-
- return reply.readInt32(buffers);
- }
-
- status_t addWindowInfosListener(
- const sp<IWindowInfosListener>& windowInfosListener) const override {
- Parcel data, reply;
- SAFE_PARCEL(data.writeInterfaceToken, ISurfaceComposer::getInterfaceDescriptor());
- SAFE_PARCEL(data.writeStrongBinder, IInterface::asBinder(windowInfosListener));
- return remote()->transact(BnSurfaceComposer::ADD_WINDOW_INFOS_LISTENER, data, &reply);
- }
-
- status_t removeWindowInfosListener(
- const sp<IWindowInfosListener>& windowInfosListener) const override {
- Parcel data, reply;
- SAFE_PARCEL(data.writeInterfaceToken, ISurfaceComposer::getInterfaceDescriptor());
- SAFE_PARCEL(data.writeStrongBinder, IInterface::asBinder(windowInfosListener));
- return remote()->transact(BnSurfaceComposer::REMOVE_WINDOW_INFOS_LISTENER, data, &reply);
- }
-
- status_t setOverrideFrameRate(uid_t uid, float frameRate) override {
- Parcel data, reply;
- SAFE_PARCEL(data.writeInterfaceToken, ISurfaceComposer::getInterfaceDescriptor());
- SAFE_PARCEL(data.writeUint32, uid);
- SAFE_PARCEL(data.writeFloat, frameRate);
-
- status_t err = remote()->transact(BnSurfaceComposer::SET_OVERRIDE_FRAME_RATE, data, &reply);
- if (err != NO_ERROR) {
- ALOGE("setOverrideFrameRate: failed to transact %s (%d)", strerror(-err), err);
- return err;
- }
-
- return NO_ERROR;
- }
};
// Out-of-line virtual method definition to trigger vtable emission in this
@@ -1031,18 +127,12 @@ IMPLEMENT_META_INTERFACE(SurfaceComposer, "android.ui.ISurfaceComposer");
status_t BnSurfaceComposer::onTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
- switch(code) {
- case CREATE_CONNECTION: {
- CHECK_INTERFACE(ISurfaceComposer, data, reply);
- sp<IBinder> b = IInterface::asBinder(createConnection());
- reply->writeStrongBinder(b);
- return NO_ERROR;
- }
+ switch (code) {
case SET_TRANSACTION_STATE: {
CHECK_INTERFACE(ISurfaceComposer, data, reply);
FrameTimelineInfo frameTimelineInfo;
- SAFE_PARCEL(frameTimelineInfo.read, data);
+ frameTimelineInfo.readFromParcel(&data);
uint32_t count = 0;
SAFE_PARCEL_READ_SIZE(data.readUint32, &count, data.dataSize());
@@ -1075,11 +165,14 @@ status_t BnSurfaceComposer::onTransact(
SAFE_PARCEL(data.readInt64, &desiredPresentTime);
SAFE_PARCEL(data.readBool, &isAutoTimestamp);
- client_cache_t uncachedBuffer;
+ SAFE_PARCEL_READ_SIZE(data.readUint32, &count, data.dataSize());
+ std::vector<client_cache_t> uncacheBuffers(count);
sp<IBinder> tmpBinder;
- SAFE_PARCEL(data.readNullableStrongBinder, &tmpBinder);
- uncachedBuffer.token = tmpBinder;
- SAFE_PARCEL(data.readUint64, &uncachedBuffer.id);
+ for (size_t i = 0; i < count; i++) {
+ SAFE_PARCEL(data.readNullableStrongBinder, &tmpBinder);
+ uncacheBuffers[i].token = tmpBinder;
+ SAFE_PARCEL(data.readUint64, &uncacheBuffers[i].id);
+ }
bool hasListenerCallbacks = false;
SAFE_PARCEL(data.readBool, &hasListenerCallbacks);
@@ -1097,646 +190,16 @@ status_t BnSurfaceComposer::onTransact(
uint64_t transactionId = -1;
SAFE_PARCEL(data.readUint64, &transactionId);
- return setTransactionState(frameTimelineInfo, state, displays, stateFlags, applyToken,
- inputWindowCommands, desiredPresentTime, isAutoTimestamp,
- uncachedBuffer, hasListenerCallbacks, listenerCallbacks,
- transactionId);
- }
- case BOOT_FINISHED: {
- CHECK_INTERFACE(ISurfaceComposer, data, reply);
- bootFinished();
- return NO_ERROR;
- }
- case AUTHENTICATE_SURFACE: {
- CHECK_INTERFACE(ISurfaceComposer, data, reply);
- sp<IGraphicBufferProducer> bufferProducer =
- interface_cast<IGraphicBufferProducer>(data.readStrongBinder());
- int32_t result = authenticateSurfaceTexture(bufferProducer) ? 1 : 0;
- reply->writeInt32(result);
- return NO_ERROR;
- }
- case GET_SUPPORTED_FRAME_TIMESTAMPS: {
- CHECK_INTERFACE(ISurfaceComposer, data, reply);
- std::vector<FrameEvent> supportedTimestamps;
- status_t result = getSupportedFrameTimestamps(&supportedTimestamps);
- status_t err = reply->writeInt32(result);
- if (err != NO_ERROR) {
- return err;
- }
- if (result != NO_ERROR) {
- return result;
- }
-
- std::vector<int32_t> supported;
- supported.reserve(supportedTimestamps.size());
- for (FrameEvent s : supportedTimestamps) {
- supported.push_back(static_cast<int32_t>(s));
- }
- return reply->writeInt32Vector(supported);
- }
- case CREATE_DISPLAY_EVENT_CONNECTION: {
- CHECK_INTERFACE(ISurfaceComposer, data, reply);
- auto vsyncSource = static_cast<ISurfaceComposer::VsyncSource>(data.readInt32());
- EventRegistrationFlags eventRegistration =
- static_cast<EventRegistration>(data.readUint32());
-
- sp<IDisplayEventConnection> connection(
- createDisplayEventConnection(vsyncSource, eventRegistration));
- reply->writeStrongBinder(IInterface::asBinder(connection));
- return NO_ERROR;
- }
- case GET_STATIC_DISPLAY_INFO: {
- CHECK_INTERFACE(ISurfaceComposer, data, reply);
- ui::StaticDisplayInfo info;
- const sp<IBinder> display = data.readStrongBinder();
- const status_t result = getStaticDisplayInfo(display, &info);
- SAFE_PARCEL(reply->writeInt32, result);
- if (result != NO_ERROR) return result;
- SAFE_PARCEL(reply->write, info);
- return NO_ERROR;
- }
- case GET_DYNAMIC_DISPLAY_INFO: {
- CHECK_INTERFACE(ISurfaceComposer, data, reply);
- ui::DynamicDisplayInfo info;
- const sp<IBinder> display = data.readStrongBinder();
- const status_t result = getDynamicDisplayInfo(display, &info);
- SAFE_PARCEL(reply->writeInt32, result);
- if (result != NO_ERROR) return result;
- SAFE_PARCEL(reply->write, info);
- return NO_ERROR;
- }
- case GET_DISPLAY_NATIVE_PRIMARIES: {
- CHECK_INTERFACE(ISurfaceComposer, data, reply);
- ui::DisplayPrimaries primaries;
- sp<IBinder> display = nullptr;
-
- status_t result = data.readStrongBinder(&display);
- if (result != NO_ERROR) {
- ALOGE("getDisplayNativePrimaries failed to readStrongBinder: %d", result);
- return result;
- }
-
- result = getDisplayNativePrimaries(display, primaries);
- reply->writeInt32(result);
- if (result == NO_ERROR) {
- memcpy(reply->writeInplace(sizeof(ui::DisplayPrimaries)), &primaries,
- sizeof(ui::DisplayPrimaries));
- }
-
- return NO_ERROR;
- }
- case SET_ACTIVE_COLOR_MODE: {
- CHECK_INTERFACE(ISurfaceComposer, data, reply);
- sp<IBinder> display = nullptr;
- status_t result = data.readStrongBinder(&display);
- if (result != NO_ERROR) {
- ALOGE("getActiveColorMode failed to readStrongBinder: %d", result);
- return result;
- }
- int32_t colorModeInt = 0;
- result = data.readInt32(&colorModeInt);
- if (result != NO_ERROR) {
- ALOGE("setActiveColorMode failed to readInt32: %d", result);
- return result;
- }
- result = setActiveColorMode(display,
- static_cast<ColorMode>(colorModeInt));
- result = reply->writeInt32(result);
- return result;
- }
- case SET_BOOT_DISPLAY_MODE: {
- CHECK_INTERFACE(ISurfaceComposer, data, reply);
- sp<IBinder> display = nullptr;
- status_t result = data.readStrongBinder(&display);
- if (result != NO_ERROR) {
- ALOGE("setBootDisplayMode failed to readStrongBinder: %d", result);
- return result;
- }
- ui::DisplayModeId displayModeId;
- result = data.readInt32(&displayModeId);
- if (result != NO_ERROR) {
- ALOGE("setBootDisplayMode failed to readInt32: %d", result);
- return result;
- }
- return setBootDisplayMode(display, displayModeId);
- }
- case CLEAR_ANIMATION_FRAME_STATS: {
- CHECK_INTERFACE(ISurfaceComposer, data, reply);
- status_t result = clearAnimationFrameStats();
- reply->writeInt32(result);
- return NO_ERROR;
- }
- case GET_ANIMATION_FRAME_STATS: {
- CHECK_INTERFACE(ISurfaceComposer, data, reply);
- FrameStats stats;
- status_t result = getAnimationFrameStats(&stats);
- reply->write(stats);
- reply->writeInt32(result);
- return NO_ERROR;
- }
- case ENABLE_VSYNC_INJECTIONS: {
- CHECK_INTERFACE(ISurfaceComposer, data, reply);
- bool enable = false;
- status_t result = data.readBool(&enable);
- if (result != NO_ERROR) {
- ALOGE("enableVSyncInjections failed to readBool: %d", result);
- return result;
- }
- return enableVSyncInjections(enable);
- }
- case INJECT_VSYNC: {
- CHECK_INTERFACE(ISurfaceComposer, data, reply);
- int64_t when = 0;
- status_t result = data.readInt64(&when);
- if (result != NO_ERROR) {
- ALOGE("enableVSyncInjections failed to readInt64: %d", result);
- return result;
- }
- return injectVSync(when);
- }
- case GET_LAYER_DEBUG_INFO: {
- CHECK_INTERFACE(ISurfaceComposer, data, reply);
- std::vector<LayerDebugInfo> outLayers;
- status_t result = getLayerDebugInfo(&outLayers);
- reply->writeInt32(result);
- if (result == NO_ERROR)
- {
- result = reply->writeParcelableVector(outLayers);
- }
- return result;
- }
- case GET_COMPOSITION_PREFERENCE: {
- CHECK_INTERFACE(ISurfaceComposer, data, reply);
- ui::Dataspace defaultDataspace;
- ui::PixelFormat defaultPixelFormat;
- ui::Dataspace wideColorGamutDataspace;
- ui::PixelFormat wideColorGamutPixelFormat;
- status_t error =
- getCompositionPreference(&defaultDataspace, &defaultPixelFormat,
- &wideColorGamutDataspace, &wideColorGamutPixelFormat);
- reply->writeInt32(error);
- if (error == NO_ERROR) {
- reply->writeInt32(static_cast<int32_t>(defaultDataspace));
- reply->writeInt32(static_cast<int32_t>(defaultPixelFormat));
- reply->writeInt32(static_cast<int32_t>(wideColorGamutDataspace));
- reply->writeInt32(static_cast<int32_t>(wideColorGamutPixelFormat));
- }
- return error;
- }
- case GET_COLOR_MANAGEMENT: {
- CHECK_INTERFACE(ISurfaceComposer, data, reply);
- bool result;
- status_t error = getColorManagement(&result);
- if (error == NO_ERROR) {
- reply->writeBool(result);
- }
- return error;
- }
- case GET_DISPLAYED_CONTENT_SAMPLING_ATTRIBUTES: {
- CHECK_INTERFACE(ISurfaceComposer, data, reply);
-
- sp<IBinder> display = data.readStrongBinder();
- ui::PixelFormat format;
- ui::Dataspace dataspace;
- uint8_t component = 0;
- auto result =
- getDisplayedContentSamplingAttributes(display, &format, &dataspace, &component);
- if (result == NO_ERROR) {
- reply->writeUint32(static_cast<uint32_t>(format));
- reply->writeUint32(static_cast<uint32_t>(dataspace));
- reply->writeUint32(static_cast<uint32_t>(component));
- }
- return result;
- }
- case SET_DISPLAY_CONTENT_SAMPLING_ENABLED: {
- CHECK_INTERFACE(ISurfaceComposer, data, reply);
-
- sp<IBinder> display = nullptr;
- bool enable = false;
- int8_t componentMask = 0;
- uint64_t maxFrames = 0;
- status_t result = data.readStrongBinder(&display);
- if (result != NO_ERROR) {
- ALOGE("setDisplayContentSamplingEnabled failure in reading Display token: %d",
- result);
- return result;
- }
-
- result = data.readBool(&enable);
- if (result != NO_ERROR) {
- ALOGE("setDisplayContentSamplingEnabled failure in reading enable: %d", result);
- return result;
- }
-
- result = data.readByte(static_cast<int8_t*>(&componentMask));
- if (result != NO_ERROR) {
- ALOGE("setDisplayContentSamplingEnabled failure in reading component mask: %d",
- result);
- return result;
- }
-
- result = data.readUint64(&maxFrames);
- if (result != NO_ERROR) {
- ALOGE("setDisplayContentSamplingEnabled failure in reading max frames: %d", result);
- return result;
- }
-
- return setDisplayContentSamplingEnabled(display, enable,
- static_cast<uint8_t>(componentMask), maxFrames);
- }
- case GET_DISPLAYED_CONTENT_SAMPLE: {
- CHECK_INTERFACE(ISurfaceComposer, data, reply);
-
- sp<IBinder> display = data.readStrongBinder();
- uint64_t maxFrames = 0;
- uint64_t timestamp = 0;
-
- status_t result = data.readUint64(&maxFrames);
- if (result != NO_ERROR) {
- ALOGE("getDisplayedContentSample failure in reading max frames: %d", result);
- return result;
- }
-
- result = data.readUint64(&timestamp);
- if (result != NO_ERROR) {
- ALOGE("getDisplayedContentSample failure in reading timestamp: %d", result);
- return result;
- }
-
- DisplayedFrameStats stats;
- result = getDisplayedContentSample(display, maxFrames, timestamp, &stats);
- if (result == NO_ERROR) {
- reply->writeUint64(stats.numFrames);
- reply->writeUint64Vector(stats.component_0_sample);
- reply->writeUint64Vector(stats.component_1_sample);
- reply->writeUint64Vector(stats.component_2_sample);
- reply->writeUint64Vector(stats.component_3_sample);
- }
- return result;
- }
- case GET_PROTECTED_CONTENT_SUPPORT: {
- CHECK_INTERFACE(ISurfaceComposer, data, reply);
- bool result;
- status_t error = getProtectedContentSupport(&result);
- if (error == NO_ERROR) {
- reply->writeBool(result);
- }
- return error;
- }
- case ADD_REGION_SAMPLING_LISTENER: {
- CHECK_INTERFACE(ISurfaceComposer, data, reply);
- Rect samplingArea;
- status_t result = data.read(samplingArea);
- if (result != NO_ERROR) {
- ALOGE("addRegionSamplingListener: Failed to read sampling area");
- return result;
- }
- sp<IBinder> stopLayerHandle;
- result = data.readNullableStrongBinder(&stopLayerHandle);
- if (result != NO_ERROR) {
- ALOGE("addRegionSamplingListener: Failed to read stop layer handle");
- return result;
- }
- sp<IRegionSamplingListener> listener;
- result = data.readNullableStrongBinder(&listener);
- if (result != NO_ERROR) {
- ALOGE("addRegionSamplingListener: Failed to read listener");
- return result;
- }
- return addRegionSamplingListener(samplingArea, stopLayerHandle, listener);
- }
- case REMOVE_REGION_SAMPLING_LISTENER: {
- CHECK_INTERFACE(ISurfaceComposer, data, reply);
- sp<IRegionSamplingListener> listener;
- status_t result = data.readNullableStrongBinder(&listener);
- if (result != NO_ERROR) {
- ALOGE("removeRegionSamplingListener: Failed to read listener");
- return result;
- }
- return removeRegionSamplingListener(listener);
- }
- case ADD_FPS_LISTENER: {
- CHECK_INTERFACE(ISurfaceComposer, data, reply);
- int32_t taskId;
- status_t result = data.readInt32(&taskId);
- if (result != NO_ERROR) {
- ALOGE("addFpsListener: Failed to read layer handle");
- return result;
- }
- sp<gui::IFpsListener> listener;
- result = data.readNullableStrongBinder(&listener);
- if (result != NO_ERROR) {
- ALOGE("addFpsListener: Failed to read listener");
- return result;
- }
- return addFpsListener(taskId, listener);
- }
- case REMOVE_FPS_LISTENER: {
- CHECK_INTERFACE(ISurfaceComposer, data, reply);
- sp<gui::IFpsListener> listener;
- status_t result = data.readNullableStrongBinder(&listener);
- if (result != NO_ERROR) {
- ALOGE("removeFpsListener: Failed to read listener");
- return result;
- }
- return removeFpsListener(listener);
- }
- case ADD_TUNNEL_MODE_ENABLED_LISTENER: {
- CHECK_INTERFACE(ISurfaceComposer, data, reply);
- sp<gui::ITunnelModeEnabledListener> listener;
- status_t result = data.readNullableStrongBinder(&listener);
- if (result != NO_ERROR) {
- ALOGE("addTunnelModeEnabledListener: Failed to read listener");
- return result;
- }
- return addTunnelModeEnabledListener(listener);
- }
- case REMOVE_TUNNEL_MODE_ENABLED_LISTENER: {
- CHECK_INTERFACE(ISurfaceComposer, data, reply);
- sp<gui::ITunnelModeEnabledListener> listener;
- status_t result = data.readNullableStrongBinder(&listener);
- if (result != NO_ERROR) {
- ALOGE("removeTunnelModeEnabledListener: Failed to read listener");
- return result;
- }
- return removeTunnelModeEnabledListener(listener);
- }
- case SET_DESIRED_DISPLAY_MODE_SPECS: {
- CHECK_INTERFACE(ISurfaceComposer, data, reply);
- sp<IBinder> displayToken = data.readStrongBinder();
- ui::DisplayModeId defaultMode;
- status_t result = data.readInt32(&defaultMode);
- if (result != NO_ERROR) {
- ALOGE("setDesiredDisplayModeSpecs: failed to read defaultMode: %d", result);
- return result;
- }
- if (defaultMode < 0) {
- ALOGE("%s: defaultMode must be non-negative but it was %d", __func__, defaultMode);
- return BAD_VALUE;
- }
- bool allowGroupSwitching;
- result = data.readBool(&allowGroupSwitching);
- if (result != NO_ERROR) {
- ALOGE("setDesiredDisplayModeSpecs: failed to read allowGroupSwitching: %d", result);
- return result;
- }
- float primaryRefreshRateMin;
- result = data.readFloat(&primaryRefreshRateMin);
- if (result != NO_ERROR) {
- ALOGE("setDesiredDisplayModeSpecs: failed to read primaryRefreshRateMin: %d",
- result);
- return result;
- }
- float primaryRefreshRateMax;
- result = data.readFloat(&primaryRefreshRateMax);
- if (result != NO_ERROR) {
- ALOGE("setDesiredDisplayModeSpecs: failed to read primaryRefreshRateMax: %d",
- result);
- return result;
- }
- float appRequestRefreshRateMin;
- result = data.readFloat(&appRequestRefreshRateMin);
- if (result != NO_ERROR) {
- ALOGE("setDesiredDisplayModeSpecs: failed to read appRequestRefreshRateMin: %d",
- result);
- return result;
- }
- float appRequestRefreshRateMax;
- result = data.readFloat(&appRequestRefreshRateMax);
- if (result != NO_ERROR) {
- ALOGE("setDesiredDisplayModeSpecs: failed to read appRequestRefreshRateMax: %d",
- result);
- return result;
- }
- result = setDesiredDisplayModeSpecs(displayToken, defaultMode, allowGroupSwitching,
- primaryRefreshRateMin, primaryRefreshRateMax,
- appRequestRefreshRateMin, appRequestRefreshRateMax);
- if (result != NO_ERROR) {
- ALOGE("setDesiredDisplayModeSpecs: failed to call setDesiredDisplayModeSpecs: "
- "%d",
- result);
- return result;
- }
- reply->writeInt32(result);
- return result;
- }
- case GET_DESIRED_DISPLAY_MODE_SPECS: {
- CHECK_INTERFACE(ISurfaceComposer, data, reply);
- sp<IBinder> displayToken = data.readStrongBinder();
- ui::DisplayModeId defaultMode;
- bool allowGroupSwitching;
- float primaryRefreshRateMin;
- float primaryRefreshRateMax;
- float appRequestRefreshRateMin;
- float appRequestRefreshRateMax;
-
- status_t result =
- getDesiredDisplayModeSpecs(displayToken, &defaultMode, &allowGroupSwitching,
- &primaryRefreshRateMin, &primaryRefreshRateMax,
- &appRequestRefreshRateMin,
- &appRequestRefreshRateMax);
- if (result != NO_ERROR) {
- ALOGE("getDesiredDisplayModeSpecs: failed to get getDesiredDisplayModeSpecs: "
- "%d",
- result);
- return result;
- }
-
- result = reply->writeInt32(defaultMode);
- if (result != NO_ERROR) {
- ALOGE("getDesiredDisplayModeSpecs: failed to write defaultMode: %d", result);
- return result;
- }
- result = reply->writeBool(allowGroupSwitching);
- if (result != NO_ERROR) {
- ALOGE("getDesiredDisplayModeSpecs: failed to write allowGroupSwitching: %d",
- result);
- return result;
- }
- result = reply->writeFloat(primaryRefreshRateMin);
- if (result != NO_ERROR) {
- ALOGE("getDesiredDisplayModeSpecs: failed to write primaryRefreshRateMin: %d",
- result);
- return result;
- }
- result = reply->writeFloat(primaryRefreshRateMax);
- if (result != NO_ERROR) {
- ALOGE("getDesiredDisplayModeSpecs: failed to write primaryRefreshRateMax: %d",
- result);
- return result;
- }
- result = reply->writeFloat(appRequestRefreshRateMin);
- if (result != NO_ERROR) {
- ALOGE("getDesiredDisplayModeSpecs: failed to write appRequestRefreshRateMin: %d",
- result);
- return result;
- }
- result = reply->writeFloat(appRequestRefreshRateMax);
- if (result != NO_ERROR) {
- ALOGE("getDesiredDisplayModeSpecs: failed to write appRequestRefreshRateMax: %d",
- result);
- return result;
- }
- reply->writeInt32(result);
- return result;
- }
- case SET_GLOBAL_SHADOW_SETTINGS: {
- CHECK_INTERFACE(ISurfaceComposer, data, reply);
-
- std::vector<float> shadowConfig;
- status_t error = data.readFloatVector(&shadowConfig);
- if (error != NO_ERROR || shadowConfig.size() != 11) {
- ALOGE("setGlobalShadowSettings: failed to read shadowConfig: %d", error);
- return error;
- }
-
- half4 ambientColor = {shadowConfig[0], shadowConfig[1], shadowConfig[2],
- shadowConfig[3]};
- half4 spotColor = {shadowConfig[4], shadowConfig[5], shadowConfig[6], shadowConfig[7]};
- float lightPosY = shadowConfig[8];
- float lightPosZ = shadowConfig[9];
- float lightRadius = shadowConfig[10];
- return setGlobalShadowSettings(ambientColor, spotColor, lightPosY, lightPosZ,
- lightRadius);
- }
- case GET_DISPLAY_DECORATION_SUPPORT: {
- CHECK_INTERFACE(ISurfaceComposer, data, reply);
- sp<IBinder> displayToken;
- SAFE_PARCEL(data.readNullableStrongBinder, &displayToken);
- std::optional<common::DisplayDecorationSupport> support;
- auto error = getDisplayDecorationSupport(displayToken, &support);
- if (error != NO_ERROR) {
- ALOGE("getDisplayDecorationSupport failed with error %d", error);
- return error;
- }
- reply->writeBool(support.has_value());
- if (support) {
- reply->writeInt32(static_cast<int32_t>(support.value().format));
- reply->writeInt32(static_cast<int32_t>(support.value().alphaInterpretation));
- }
- return error;
- }
- case SET_FRAME_RATE: {
- CHECK_INTERFACE(ISurfaceComposer, data, reply);
- sp<IBinder> binder;
- SAFE_PARCEL(data.readStrongBinder, &binder);
-
- sp<IGraphicBufferProducer> surface = interface_cast<IGraphicBufferProducer>(binder);
- if (!surface) {
- ALOGE("setFrameRate: failed to cast to IGraphicBufferProducer");
- return BAD_VALUE;
- }
- float frameRate;
- SAFE_PARCEL(data.readFloat, &frameRate);
-
- int8_t compatibility;
- SAFE_PARCEL(data.readByte, &compatibility);
-
- int8_t changeFrameRateStrategy;
- SAFE_PARCEL(data.readByte, &changeFrameRateStrategy);
-
- status_t result =
- setFrameRate(surface, frameRate, compatibility, changeFrameRateStrategy);
- reply->writeInt32(result);
- return NO_ERROR;
- }
- case SET_FRAME_TIMELINE_INFO: {
- CHECK_INTERFACE(ISurfaceComposer, data, reply);
- sp<IBinder> binder;
- status_t err = data.readStrongBinder(&binder);
- if (err != NO_ERROR) {
- ALOGE("setFrameTimelineInfo: failed to read strong binder: %s (%d)", strerror(-err),
- -err);
- return err;
- }
- sp<IGraphicBufferProducer> surface = interface_cast<IGraphicBufferProducer>(binder);
- if (!surface) {
- ALOGE("setFrameTimelineInfo: failed to cast to IGraphicBufferProducer: %s (%d)",
- strerror(-err), -err);
- return err;
- }
-
- FrameTimelineInfo frameTimelineInfo;
- SAFE_PARCEL(frameTimelineInfo.read, data);
-
- status_t result = setFrameTimelineInfo(surface, frameTimelineInfo);
- reply->writeInt32(result);
- return NO_ERROR;
- }
- case ADD_TRANSACTION_TRACE_LISTENER: {
- CHECK_INTERFACE(ISurfaceComposer, data, reply);
- sp<gui::ITransactionTraceListener> listener;
- SAFE_PARCEL(data.readStrongBinder, &listener);
-
- return addTransactionTraceListener(listener);
- }
- case GET_GPU_CONTEXT_PRIORITY: {
- CHECK_INTERFACE(ISurfaceComposer, data, reply);
- int priority = getGPUContextPriority();
- SAFE_PARCEL(reply->writeInt32, priority);
- return NO_ERROR;
- }
- case GET_MAX_ACQUIRED_BUFFER_COUNT: {
- CHECK_INTERFACE(ISurfaceComposer, data, reply);
- int buffers = 0;
- int err = getMaxAcquiredBufferCount(&buffers);
- if (err != NO_ERROR) {
- return err;
+ SAFE_PARCEL_READ_SIZE(data.readUint32, &count, data.dataSize());
+ std::vector<uint64_t> mergedTransactions(count);
+ for (size_t i = 0; i < count; i++) {
+ SAFE_PARCEL(data.readUint64, &mergedTransactions[i]);
}
- SAFE_PARCEL(reply->writeInt32, buffers);
- return NO_ERROR;
- }
- case OVERRIDE_HDR_TYPES: {
- CHECK_INTERFACE(ISurfaceComposer, data, reply);
- sp<IBinder> display = nullptr;
- SAFE_PARCEL(data.readStrongBinder, &display);
- std::vector<int32_t> hdrTypes;
- SAFE_PARCEL(data.readInt32Vector, &hdrTypes);
-
- std::vector<ui::Hdr> hdrTypesVector;
- for (int i : hdrTypes) {
- hdrTypesVector.push_back(static_cast<ui::Hdr>(i));
- }
- return overrideHdrTypes(display, hdrTypesVector);
- }
- case ON_PULL_ATOM: {
- CHECK_INTERFACE(ISurfaceComposer, data, reply);
- int32_t atomId = 0;
- SAFE_PARCEL(data.readInt32, &atomId);
-
- std::string pulledData;
- bool success;
- status_t err = onPullAtom(atomId, &pulledData, &success);
- SAFE_PARCEL(reply->writeByteArray, pulledData.size(),
- reinterpret_cast<const uint8_t*>(pulledData.data()));
- SAFE_PARCEL(reply->writeBool, success);
- return err;
- }
- case ADD_WINDOW_INFOS_LISTENER: {
- CHECK_INTERFACE(ISurfaceComposer, data, reply);
- sp<IWindowInfosListener> listener;
- SAFE_PARCEL(data.readStrongBinder, &listener);
-
- return addWindowInfosListener(listener);
- }
- case REMOVE_WINDOW_INFOS_LISTENER: {
- CHECK_INTERFACE(ISurfaceComposer, data, reply);
- sp<IWindowInfosListener> listener;
- SAFE_PARCEL(data.readStrongBinder, &listener);
-
- return removeWindowInfosListener(listener);
- }
- case SET_OVERRIDE_FRAME_RATE: {
- CHECK_INTERFACE(ISurfaceComposer, data, reply);
-
- uid_t uid;
- SAFE_PARCEL(data.readUint32, &uid);
-
- float frameRate;
- SAFE_PARCEL(data.readFloat, &frameRate);
-
- return setOverrideFrameRate(uid, frameRate);
+ return setTransactionState(frameTimelineInfo, state, displays, stateFlags, applyToken,
+ std::move(inputWindowCommands), desiredPresentTime,
+ isAutoTimestamp, uncacheBuffers, hasListenerCallbacks,
+ listenerCallbacks, transactionId, mergedTransactions);
}
default: {
return BBinder::onTransact(code, data, reply, flags);
diff --git a/libs/gui/ISurfaceComposerClient.cpp b/libs/gui/ISurfaceComposerClient.cpp
deleted file mode 100644
index 5e7a7ec67b..0000000000
--- a/libs/gui/ISurfaceComposerClient.cpp
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-// tag as surfaceflinger
-#define LOG_TAG "SurfaceFlinger"
-
-#include <gui/ISurfaceComposerClient.h>
-
-#include <gui/IGraphicBufferProducer.h>
-
-#include <binder/SafeInterface.h>
-
-#include <ui/FrameStats.h>
-
-namespace android {
-
-namespace { // Anonymous
-
-enum class Tag : uint32_t {
- CREATE_SURFACE = IBinder::FIRST_CALL_TRANSACTION,
- CREATE_WITH_SURFACE_PARENT,
- CLEAR_LAYER_FRAME_STATS,
- GET_LAYER_FRAME_STATS,
- MIRROR_SURFACE,
- LAST = MIRROR_SURFACE,
-};
-
-} // Anonymous namespace
-
-class BpSurfaceComposerClient : public SafeBpInterface<ISurfaceComposerClient> {
-public:
- explicit BpSurfaceComposerClient(const sp<IBinder>& impl)
- : SafeBpInterface<ISurfaceComposerClient>(impl, "BpSurfaceComposerClient") {}
-
- ~BpSurfaceComposerClient() override;
-
- status_t createSurface(const String8& name, uint32_t width, uint32_t height, PixelFormat format,
- uint32_t flags, const sp<IBinder>& parent, LayerMetadata metadata,
- sp<IBinder>* handle, sp<IGraphicBufferProducer>* gbp,
- int32_t* outLayerId, uint32_t* outTransformHint) override {
- return callRemote<decltype(&ISurfaceComposerClient::createSurface)>(Tag::CREATE_SURFACE,
- name, width, height,
- format, flags, parent,
- std::move(metadata),
- handle, gbp, outLayerId,
- outTransformHint);
- }
-
- status_t createWithSurfaceParent(const String8& name, uint32_t width, uint32_t height,
- PixelFormat format, uint32_t flags,
- const sp<IGraphicBufferProducer>& parent,
- LayerMetadata metadata, sp<IBinder>* handle,
- sp<IGraphicBufferProducer>* gbp, int32_t* outLayerId,
- uint32_t* outTransformHint) override {
- return callRemote<decltype(
- &ISurfaceComposerClient::createWithSurfaceParent)>(Tag::CREATE_WITH_SURFACE_PARENT,
- name, width, height, format,
- flags, parent,
- std::move(metadata), handle, gbp,
- outLayerId, outTransformHint);
- }
-
- status_t clearLayerFrameStats(const sp<IBinder>& handle) const override {
- return callRemote<decltype(
- &ISurfaceComposerClient::clearLayerFrameStats)>(Tag::CLEAR_LAYER_FRAME_STATS,
- handle);
- }
-
- status_t getLayerFrameStats(const sp<IBinder>& handle, FrameStats* outStats) const override {
- return callRemote<decltype(
- &ISurfaceComposerClient::getLayerFrameStats)>(Tag::GET_LAYER_FRAME_STATS, handle,
- outStats);
- }
-
- status_t mirrorSurface(const sp<IBinder>& mirrorFromHandle, sp<IBinder>* outHandle,
- int32_t* outLayerId) override {
- return callRemote<decltype(&ISurfaceComposerClient::mirrorSurface)>(Tag::MIRROR_SURFACE,
- mirrorFromHandle,
- outHandle, outLayerId);
- }
-};
-
-// Out-of-line virtual method definition to trigger vtable emission in this
-// translation unit (see clang warning -Wweak-vtables)
-BpSurfaceComposerClient::~BpSurfaceComposerClient() {}
-
-IMPLEMENT_META_INTERFACE(SurfaceComposerClient, "android.ui.ISurfaceComposerClient");
-
-// ----------------------------------------------------------------------
-
-status_t BnSurfaceComposerClient::onTransact(uint32_t code, const Parcel& data, Parcel* reply,
- uint32_t flags) {
- if (code < IBinder::FIRST_CALL_TRANSACTION || code > static_cast<uint32_t>(Tag::LAST)) {
- return BBinder::onTransact(code, data, reply, flags);
- }
- auto tag = static_cast<Tag>(code);
- switch (tag) {
- case Tag::CREATE_SURFACE:
- return callLocal(data, reply, &ISurfaceComposerClient::createSurface);
- case Tag::CREATE_WITH_SURFACE_PARENT:
- return callLocal(data, reply, &ISurfaceComposerClient::createWithSurfaceParent);
- case Tag::CLEAR_LAYER_FRAME_STATS:
- return callLocal(data, reply, &ISurfaceComposerClient::clearLayerFrameStats);
- case Tag::GET_LAYER_FRAME_STATS:
- return callLocal(data, reply, &ISurfaceComposerClient::getLayerFrameStats);
- case Tag::MIRROR_SURFACE:
- return callLocal(data, reply, &ISurfaceComposerClient::mirrorSurface);
- }
-}
-
-} // namespace android
diff --git a/libs/gui/ITransactionCompletedListener.cpp b/libs/gui/ITransactionCompletedListener.cpp
index e4b8bad8f8..ffe79a3a03 100644
--- a/libs/gui/ITransactionCompletedListener.cpp
+++ b/libs/gui/ITransactionCompletedListener.cpp
@@ -17,6 +17,9 @@
#define LOG_TAG "ITransactionCompletedListener"
//#define LOG_NDEBUG 0
+#include <cstdint>
+#include <optional>
+
#include <gui/ISurfaceComposer.h>
#include <gui/ITransactionCompletedListener.h>
#include <gui/LayerState.h>
@@ -30,11 +33,18 @@ enum class Tag : uint32_t {
ON_TRANSACTION_COMPLETED = IBinder::FIRST_CALL_TRANSACTION,
ON_RELEASE_BUFFER,
ON_TRANSACTION_QUEUE_STALLED,
- LAST = ON_RELEASE_BUFFER,
+ ON_TRUSTED_PRESENTATION_CHANGED,
+ LAST = ON_TRUSTED_PRESENTATION_CHANGED,
};
} // Anonymous namespace
+namespace { // Anonymous
+
+constexpr int32_t kSerializedCallbackTypeOnCompelteWithJankData = 2;
+
+} // Anonymous namespace
+
status_t FrameEventHistoryStats::writeToParcel(Parcel* output) const {
status_t err = output->writeUint64(frameNumber);
if (err != NO_ERROR) return err;
@@ -126,7 +136,12 @@ status_t SurfaceStats::writeToParcel(Parcel* output) const {
} else {
SAFE_PARCEL(output->writeBool, false);
}
- SAFE_PARCEL(output->writeUint32, transformHint);
+
+ SAFE_PARCEL(output->writeBool, transformHint.has_value());
+ if (transformHint.has_value()) {
+ output->writeUint32(transformHint.value());
+ }
+
SAFE_PARCEL(output->writeUint32, currentMaxAcquiredBufferCount);
SAFE_PARCEL(output->writeParcelable, eventStats);
SAFE_PARCEL(output->writeInt32, static_cast<int32_t>(jankData.size()));
@@ -156,7 +171,16 @@ status_t SurfaceStats::readFromParcel(const Parcel* input) {
previousReleaseFence = new Fence();
SAFE_PARCEL(input->read, *previousReleaseFence);
}
- SAFE_PARCEL(input->readUint32, &transformHint);
+ bool hasTransformHint = false;
+ SAFE_PARCEL(input->readBool, &hasTransformHint);
+ if (hasTransformHint) {
+ uint32_t tempTransformHint;
+ SAFE_PARCEL(input->readUint32, &tempTransformHint);
+ transformHint = std::make_optional(tempTransformHint);
+ } else {
+ transformHint = std::nullopt;
+ }
+
SAFE_PARCEL(input->readUint32, &currentMaxAcquiredBufferCount);
SAFE_PARCEL(input->readParcelable, &eventStats);
@@ -273,15 +297,22 @@ public:
void onReleaseBuffer(ReleaseCallbackId callbackId, sp<Fence> releaseFence,
uint32_t currentMaxAcquiredBufferCount) override {
- callRemoteAsync<decltype(
- &ITransactionCompletedListener::onReleaseBuffer)>(Tag::ON_RELEASE_BUFFER,
- callbackId, releaseFence,
- currentMaxAcquiredBufferCount);
+ callRemoteAsync<decltype(&ITransactionCompletedListener::
+ onReleaseBuffer)>(Tag::ON_RELEASE_BUFFER, callbackId,
+ releaseFence,
+ currentMaxAcquiredBufferCount);
+ }
+
+ void onTransactionQueueStalled(const String8& reason) override {
+ callRemoteAsync<
+ decltype(&ITransactionCompletedListener::
+ onTransactionQueueStalled)>(Tag::ON_TRANSACTION_QUEUE_STALLED,
+ reason);
}
- void onTransactionQueueStalled() override {
- callRemoteAsync<decltype(&ITransactionCompletedListener::onTransactionQueueStalled)>(
- Tag::ON_TRANSACTION_QUEUE_STALLED);
+ void onTrustedPresentationChanged(int id, bool inTrustedPresentationState) override {
+ callRemoteAsync<decltype(&ITransactionCompletedListener::onTrustedPresentationChanged)>(
+ Tag::ON_TRUSTED_PRESENTATION_CHANGED, id, inTrustedPresentationState);
}
};
@@ -306,6 +337,9 @@ status_t BnTransactionCompletedListener::onTransact(uint32_t code, const Parcel&
case Tag::ON_TRANSACTION_QUEUE_STALLED:
return callLocalAsync(data, reply,
&ITransactionCompletedListener::onTransactionQueueStalled);
+ case Tag::ON_TRUSTED_PRESENTATION_CHANGED:
+ return callLocalAsync(data, reply,
+ &ITransactionCompletedListener::onTrustedPresentationChanged);
}
}
@@ -321,7 +355,11 @@ ListenerCallbacks ListenerCallbacks::filter(CallbackId::Type type) const {
status_t CallbackId::writeToParcel(Parcel* output) const {
SAFE_PARCEL(output->writeInt64, id);
- SAFE_PARCEL(output->writeInt32, static_cast<int32_t>(type));
+ if (type == Type::ON_COMPLETE && includeJankData) {
+ SAFE_PARCEL(output->writeInt32, kSerializedCallbackTypeOnCompelteWithJankData);
+ } else {
+ SAFE_PARCEL(output->writeInt32, static_cast<int32_t>(type));
+ }
return NO_ERROR;
}
@@ -329,7 +367,13 @@ status_t CallbackId::readFromParcel(const Parcel* input) {
SAFE_PARCEL(input->readInt64, &id);
int32_t typeAsInt;
SAFE_PARCEL(input->readInt32, &typeAsInt);
- type = static_cast<CallbackId::Type>(typeAsInt);
+ if (typeAsInt == kSerializedCallbackTypeOnCompelteWithJankData) {
+ type = Type::ON_COMPLETE;
+ includeJankData = true;
+ } else {
+ type = static_cast<CallbackId::Type>(typeAsInt);
+ includeJankData = false;
+ }
return NO_ERROR;
}
diff --git a/libs/gui/LayerDebugInfo.cpp b/libs/gui/LayerDebugInfo.cpp
index ea5fb293a6..15b2221464 100644
--- a/libs/gui/LayerDebugInfo.cpp
+++ b/libs/gui/LayerDebugInfo.cpp
@@ -27,7 +27,7 @@ using android::base::StringAppendF;
#define RETURN_ON_ERROR(X) do {status_t res = (X); if (res != NO_ERROR) return res;} while(false)
-namespace android {
+namespace android::gui {
status_t LayerDebugInfo::writeToParcel(Parcel* parcel) const {
RETURN_ON_ERROR(parcel->writeCString(mName.c_str()));
@@ -149,4 +149,4 @@ std::string to_string(const LayerDebugInfo& info) {
return result;
}
-} // android
+} // namespace android::gui
diff --git a/libs/gui/LayerMetadata.cpp b/libs/gui/LayerMetadata.cpp
index 189d51a4c1..4e12fd330c 100644
--- a/libs/gui/LayerMetadata.cpp
+++ b/libs/gui/LayerMetadata.cpp
@@ -23,7 +23,7 @@
using android::base::StringPrintf;
-namespace android {
+namespace android::gui {
LayerMetadata::LayerMetadata() = default;
@@ -144,4 +144,4 @@ std::string LayerMetadata::itemToString(uint32_t key, const char* separator) con
}
}
-} // namespace android
+} // namespace android::gui
diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp
index 74e6ae6a9b..2322b70d1c 100644
--- a/libs/gui/LayerState.cpp
+++ b/libs/gui/LayerState.cpp
@@ -19,15 +19,36 @@
#include <cinttypes>
#include <cmath>
+#include <android/gui/ISurfaceComposerClient.h>
#include <android/native_window.h>
#include <binder/Parcel.h>
#include <gui/IGraphicBufferProducer.h>
-#include <gui/ISurfaceComposerClient.h>
#include <gui/LayerState.h>
+#include <gui/SurfaceControl.h>
#include <private/gui/ParcelUtils.h>
#include <system/window.h>
#include <utils/Errors.h>
+#define CHECK_DIFF(DIFF_RESULT, CHANGE_FLAG, OTHER, FIELD) \
+ { \
+ if ((OTHER.what & CHANGE_FLAG) && (FIELD != OTHER.FIELD)) { \
+ DIFF_RESULT |= CHANGE_FLAG; \
+ } \
+ }
+
+#define CHECK_DIFF2(DIFF_RESULT, CHANGE_FLAG, OTHER, FIELD1, FIELD2) \
+ { \
+ CHECK_DIFF(DIFF_RESULT, CHANGE_FLAG, OTHER, FIELD1) \
+ CHECK_DIFF(DIFF_RESULT, CHANGE_FLAG, OTHER, FIELD2) \
+ }
+
+#define CHECK_DIFF3(DIFF_RESULT, CHANGE_FLAG, OTHER, FIELD1, FIELD2, FIELD3) \
+ { \
+ CHECK_DIFF(DIFF_RESULT, CHANGE_FLAG, OTHER, FIELD1) \
+ CHECK_DIFF(DIFF_RESULT, CHANGE_FLAG, OTHER, FIELD2) \
+ CHECK_DIFF(DIFF_RESULT, CHANGE_FLAG, OTHER, FIELD3) \
+ }
+
namespace android {
using gui::FocusRequest;
@@ -40,22 +61,20 @@ layer_state_t::layer_state_t()
x(0),
y(0),
z(0),
- w(0),
- h(0),
- alpha(0),
flags(0),
mask(0),
reserved(0),
cornerRadius(0.0f),
backgroundBlurRadius(0),
- transform(0),
+ color(0),
+ bufferTransform(0),
transformToDisplayInverse(false),
crop(Rect::INVALID_RECT),
dataspace(ui::Dataspace::UNKNOWN),
surfaceDamageRegion(),
api(-1),
colorTransform(mat4()),
- bgColorAlpha(0),
+ bgColor(0),
bgColorDataspace(ui::Dataspace::UNKNOWN),
colorSpaceAgnostic(false),
shadowRadius(0.0f),
@@ -63,9 +82,11 @@ layer_state_t::layer_state_t()
frameRate(0.0f),
frameRateCompatibility(ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT),
changeFrameRateStrategy(ANATIVEWINDOW_CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS),
+ defaultFrameRateCompatibility(ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT),
fixedTransformHint(ui::Transform::ROT_INVALID),
autoRefresh(false),
isTrustedOverlay(false),
+ borderEnabled(false),
bufferCrop(Rect::INVALID_RECT),
destinationFrame(Rect::INVALID_RECT),
dropInputMode(gui::DropInputMode::NONE) {
@@ -82,25 +103,27 @@ status_t layer_state_t::write(Parcel& output) const
SAFE_PARCEL(output.writeFloat, x);
SAFE_PARCEL(output.writeFloat, y);
SAFE_PARCEL(output.writeInt32, z);
- SAFE_PARCEL(output.writeUint32, w);
- SAFE_PARCEL(output.writeUint32, h);
SAFE_PARCEL(output.writeUint32, layerStack.id);
- SAFE_PARCEL(output.writeFloat, alpha);
SAFE_PARCEL(output.writeUint32, flags);
SAFE_PARCEL(output.writeUint32, mask);
SAFE_PARCEL(matrix.write, output);
SAFE_PARCEL(output.write, crop);
- SAFE_PARCEL(SurfaceControl::writeNullableToParcel, output, reparentSurfaceControl);
SAFE_PARCEL(SurfaceControl::writeNullableToParcel, output, relativeLayerSurfaceControl);
SAFE_PARCEL(SurfaceControl::writeNullableToParcel, output, parentSurfaceControlForChild);
SAFE_PARCEL(output.writeFloat, color.r);
SAFE_PARCEL(output.writeFloat, color.g);
SAFE_PARCEL(output.writeFloat, color.b);
+ SAFE_PARCEL(output.writeFloat, color.a);
SAFE_PARCEL(windowInfoHandle->writeToParcel, &output);
SAFE_PARCEL(output.write, transparentRegion);
- SAFE_PARCEL(output.writeUint32, transform);
+ SAFE_PARCEL(output.writeUint32, bufferTransform);
SAFE_PARCEL(output.writeBool, transformToDisplayInverse);
-
+ SAFE_PARCEL(output.writeBool, borderEnabled);
+ SAFE_PARCEL(output.writeFloat, borderWidth);
+ SAFE_PARCEL(output.writeFloat, borderColor.r);
+ SAFE_PARCEL(output.writeFloat, borderColor.g);
+ SAFE_PARCEL(output.writeFloat, borderColor.b);
+ SAFE_PARCEL(output.writeFloat, borderColor.a);
SAFE_PARCEL(output.writeUint32, static_cast<uint32_t>(dataspace));
SAFE_PARCEL(output.write, hdrMetadata);
SAFE_PARCEL(output.write, surfaceDamageRegion);
@@ -117,7 +140,10 @@ status_t layer_state_t::write(Parcel& output) const
SAFE_PARCEL(output.writeFloat, cornerRadius);
SAFE_PARCEL(output.writeUint32, backgroundBlurRadius);
SAFE_PARCEL(output.writeParcelable, metadata);
- SAFE_PARCEL(output.writeFloat, bgColorAlpha);
+ SAFE_PARCEL(output.writeFloat, bgColor.r);
+ SAFE_PARCEL(output.writeFloat, bgColor.g);
+ SAFE_PARCEL(output.writeFloat, bgColor.b);
+ SAFE_PARCEL(output.writeFloat, bgColor.a);
SAFE_PARCEL(output.writeUint32, static_cast<uint32_t>(bgColorDataspace));
SAFE_PARCEL(output.writeBool, colorSpaceAgnostic);
SAFE_PARCEL(output.writeVectorSize, listeners);
@@ -131,6 +157,7 @@ status_t layer_state_t::write(Parcel& output) const
SAFE_PARCEL(output.writeFloat, frameRate);
SAFE_PARCEL(output.writeByte, frameRateCompatibility);
SAFE_PARCEL(output.writeByte, changeFrameRateStrategy);
+ SAFE_PARCEL(output.writeByte, defaultFrameRateCompatibility);
SAFE_PARCEL(output.writeUint32, fixedTransformHint);
SAFE_PARCEL(output.writeBool, autoRefresh);
SAFE_PARCEL(output.writeBool, dimmingEnabled);
@@ -161,6 +188,11 @@ status_t layer_state_t::write(Parcel& output) const
if (hasBufferData) {
SAFE_PARCEL(output.writeParcelable, *bufferData);
}
+ SAFE_PARCEL(output.writeParcelable, trustedPresentationThresholds);
+ SAFE_PARCEL(output.writeParcelable, trustedPresentationListener);
+ SAFE_PARCEL(output.writeFloat, currentHdrSdrRatio);
+ SAFE_PARCEL(output.writeFloat, desiredHdrSdrRatio);
+ SAFE_PARCEL(output.writeInt32, static_cast<int32_t>(cachingHint))
return NO_ERROR;
}
@@ -172,10 +204,7 @@ status_t layer_state_t::read(const Parcel& input)
SAFE_PARCEL(input.readFloat, &x);
SAFE_PARCEL(input.readFloat, &y);
SAFE_PARCEL(input.readInt32, &z);
- SAFE_PARCEL(input.readUint32, &w);
- SAFE_PARCEL(input.readUint32, &h);
SAFE_PARCEL(input.readUint32, &layerStack.id);
- SAFE_PARCEL(input.readFloat, &alpha);
SAFE_PARCEL(input.readUint32, &flags);
@@ -183,7 +212,6 @@ status_t layer_state_t::read(const Parcel& input)
SAFE_PARCEL(matrix.read, input);
SAFE_PARCEL(input.read, crop);
- SAFE_PARCEL(SurfaceControl::readNullableFromParcel, input, &reparentSurfaceControl);
SAFE_PARCEL(SurfaceControl::readNullableFromParcel, input, &relativeLayerSurfaceControl);
SAFE_PARCEL(SurfaceControl::readNullableFromParcel, input, &parentSurfaceControlForChild);
@@ -195,11 +223,25 @@ status_t layer_state_t::read(const Parcel& input)
color.g = tmpFloat;
SAFE_PARCEL(input.readFloat, &tmpFloat);
color.b = tmpFloat;
+ SAFE_PARCEL(input.readFloat, &tmpFloat);
+ color.a = tmpFloat;
+
SAFE_PARCEL(windowInfoHandle->readFromParcel, &input);
SAFE_PARCEL(input.read, transparentRegion);
- SAFE_PARCEL(input.readUint32, &transform);
+ SAFE_PARCEL(input.readUint32, &bufferTransform);
SAFE_PARCEL(input.readBool, &transformToDisplayInverse);
+ SAFE_PARCEL(input.readBool, &borderEnabled);
+ SAFE_PARCEL(input.readFloat, &tmpFloat);
+ borderWidth = tmpFloat;
+ SAFE_PARCEL(input.readFloat, &tmpFloat);
+ borderColor.r = tmpFloat;
+ SAFE_PARCEL(input.readFloat, &tmpFloat);
+ borderColor.g = tmpFloat;
+ SAFE_PARCEL(input.readFloat, &tmpFloat);
+ borderColor.b = tmpFloat;
+ SAFE_PARCEL(input.readFloat, &tmpFloat);
+ borderColor.a = tmpFloat;
uint32_t tmpUint32 = 0;
SAFE_PARCEL(input.readUint32, &tmpUint32);
@@ -220,7 +262,14 @@ status_t layer_state_t::read(const Parcel& input)
SAFE_PARCEL(input.readUint32, &backgroundBlurRadius);
SAFE_PARCEL(input.readParcelable, &metadata);
- SAFE_PARCEL(input.readFloat, &bgColorAlpha);
+ SAFE_PARCEL(input.readFloat, &tmpFloat);
+ bgColor.r = tmpFloat;
+ SAFE_PARCEL(input.readFloat, &tmpFloat);
+ bgColor.g = tmpFloat;
+ SAFE_PARCEL(input.readFloat, &tmpFloat);
+ bgColor.b = tmpFloat;
+ SAFE_PARCEL(input.readFloat, &tmpFloat);
+ bgColor.a = tmpFloat;
SAFE_PARCEL(input.readUint32, &tmpUint32);
bgColorDataspace = static_cast<ui::Dataspace>(tmpUint32);
SAFE_PARCEL(input.readBool, &colorSpaceAgnostic);
@@ -240,6 +289,7 @@ status_t layer_state_t::read(const Parcel& input)
SAFE_PARCEL(input.readFloat, &frameRate);
SAFE_PARCEL(input.readByte, &frameRateCompatibility);
SAFE_PARCEL(input.readByte, &changeFrameRateStrategy);
+ SAFE_PARCEL(input.readByte, &defaultFrameRateCompatibility);
SAFE_PARCEL(input.readUint32, &tmpUint32);
fixedTransformHint = static_cast<ui::Transform::RotationFlags>(tmpUint32);
SAFE_PARCEL(input.readBool, &autoRefresh);
@@ -280,6 +330,19 @@ status_t layer_state_t::read(const Parcel& input)
} else {
bufferData = nullptr;
}
+
+ SAFE_PARCEL(input.readParcelable, &trustedPresentationThresholds);
+ SAFE_PARCEL(input.readParcelable, &trustedPresentationListener);
+
+ SAFE_PARCEL(input.readFloat, &tmpFloat);
+ currentHdrSdrRatio = tmpFloat;
+ SAFE_PARCEL(input.readFloat, &tmpFloat);
+ desiredHdrSdrRatio = tmpFloat;
+
+ int32_t tmpInt32;
+ SAFE_PARCEL(input.readInt32, &tmpInt32);
+ cachingHint = static_cast<gui::CachingHint>(tmpInt32);
+
return NO_ERROR;
}
@@ -458,14 +521,9 @@ void layer_state_t::merge(const layer_state_t& other) {
what &= ~eRelativeLayerChanged;
z = other.z;
}
- if (other.what & eSizeChanged) {
- what |= eSizeChanged;
- w = other.w;
- h = other.h;
- }
if (other.what & eAlphaChanged) {
what |= eAlphaChanged;
- alpha = other.alpha;
+ color.a = other.color.a;
}
if (other.what & eMatrixChanged) {
what |= eMatrixChanged;
@@ -507,12 +565,9 @@ void layer_state_t::merge(const layer_state_t& other) {
what |= eReparent;
parentSurfaceControlForChild = other.parentSurfaceControlForChild;
}
- if (other.what & eDestroySurface) {
- what |= eDestroySurface;
- }
- if (other.what & eTransformChanged) {
- what |= eTransformChanged;
- transform = other.transform;
+ if (other.what & eBufferTransformChanged) {
+ what |= eBufferTransformChanged;
+ bufferTransform = other.bufferTransform;
}
if (other.what & eTransformToDisplayInverseChanged) {
what |= eTransformToDisplayInverseChanged;
@@ -526,10 +581,24 @@ void layer_state_t::merge(const layer_state_t& other) {
what |= eBufferChanged;
bufferData = other.bufferData;
}
+ if (other.what & eTrustedPresentationInfoChanged) {
+ what |= eTrustedPresentationInfoChanged;
+ trustedPresentationListener = other.trustedPresentationListener;
+ trustedPresentationThresholds = other.trustedPresentationThresholds;
+ }
if (other.what & eDataspaceChanged) {
what |= eDataspaceChanged;
dataspace = other.dataspace;
}
+ if (other.what & eExtendedRangeBrightnessChanged) {
+ what |= eExtendedRangeBrightnessChanged;
+ desiredHdrSdrRatio = other.desiredHdrSdrRatio;
+ currentHdrSdrRatio = other.currentHdrSdrRatio;
+ }
+ if (other.what & eCachingHintChanged) {
+ what |= eCachingHintChanged;
+ cachingHint = other.cachingHint;
+ }
if (other.what & eHdrMetadataChanged) {
what |= eHdrMetadataChanged;
hdrMetadata = other.hdrMetadata;
@@ -559,8 +628,7 @@ void layer_state_t::merge(const layer_state_t& other) {
}
if (other.what & eBackgroundColorChanged) {
what |= eBackgroundColorChanged;
- color = other.color;
- bgColorAlpha = other.bgColorAlpha;
+ bgColor = other.bgColor;
bgColorDataspace = other.bgColorDataspace;
}
if (other.what & eMetadataChanged) {
@@ -571,6 +639,16 @@ void layer_state_t::merge(const layer_state_t& other) {
what |= eShadowRadiusChanged;
shadowRadius = other.shadowRadius;
}
+ if (other.what & eRenderBorderChanged) {
+ what |= eRenderBorderChanged;
+ borderEnabled = other.borderEnabled;
+ borderWidth = other.borderWidth;
+ borderColor = other.borderColor;
+ }
+ if (other.what & eDefaultFrameRateCompatibilityChanged) {
+ what |= eDefaultFrameRateCompatibilityChanged;
+ defaultFrameRateCompatibility = other.defaultFrameRateCompatibility;
+ }
if (other.what & eFrameRateSelectionPriority) {
what |= eFrameRateSelectionPriority;
frameRateSelectionPriority = other.frameRateSelectionPriority;
@@ -614,7 +692,7 @@ void layer_state_t::merge(const layer_state_t& other) {
}
if (other.what & eColorChanged) {
what |= eColorChanged;
- color = other.color;
+ color.rgb = other.color.rgb;
}
if (other.what & eColorSpaceAgnosticChanged) {
what |= eColorSpaceAgnosticChanged;
@@ -624,6 +702,9 @@ void layer_state_t::merge(const layer_state_t& other) {
what |= eDimmingEnabledChanged;
dimmingEnabled = other.dimmingEnabled;
}
+ if (other.what & eFlushJankData) {
+ what |= eFlushJankData;
+ }
if ((other.what & what) != other.what) {
ALOGE("Unmerged SurfaceComposer Transaction properties. LayerState::merge needs updating? "
"other.what=0x%" PRIX64 " what=0x%" PRIX64 " unmerged flags=0x%" PRIX64,
@@ -631,12 +712,83 @@ void layer_state_t::merge(const layer_state_t& other) {
}
}
+uint64_t layer_state_t::diff(const layer_state_t& other) const {
+ uint64_t diff = 0;
+ CHECK_DIFF2(diff, ePositionChanged, other, x, y);
+ if (other.what & eLayerChanged) {
+ diff |= eLayerChanged;
+ diff &= ~eRelativeLayerChanged;
+ }
+ CHECK_DIFF(diff, eAlphaChanged, other, color.a);
+ CHECK_DIFF(diff, eMatrixChanged, other, matrix);
+ if (other.what & eTransparentRegionChanged &&
+ (!transparentRegion.hasSameRects(other.transparentRegion))) {
+ diff |= eTransparentRegionChanged;
+ }
+ if (other.what & eFlagsChanged) {
+ uint64_t changedFlags = (flags & other.mask) ^ (other.flags & other.mask);
+ if (changedFlags) diff |= eFlagsChanged;
+ }
+ CHECK_DIFF(diff, eLayerStackChanged, other, layerStack);
+ CHECK_DIFF(diff, eCornerRadiusChanged, other, cornerRadius);
+ CHECK_DIFF(diff, eBackgroundBlurRadiusChanged, other, backgroundBlurRadius);
+ if (other.what & eBlurRegionsChanged) diff |= eBlurRegionsChanged;
+ if (other.what & eRelativeLayerChanged) {
+ diff |= eRelativeLayerChanged;
+ diff &= ~eLayerChanged;
+ }
+ if (other.what & eReparent &&
+ !SurfaceControl::isSameSurface(parentSurfaceControlForChild,
+ other.parentSurfaceControlForChild)) {
+ diff |= eReparent;
+ }
+ CHECK_DIFF(diff, eBufferTransformChanged, other, bufferTransform);
+ CHECK_DIFF(diff, eTransformToDisplayInverseChanged, other, transformToDisplayInverse);
+ CHECK_DIFF(diff, eCropChanged, other, crop);
+ if (other.what & eBufferChanged) diff |= eBufferChanged;
+ CHECK_DIFF(diff, eDataspaceChanged, other, dataspace);
+ CHECK_DIFF2(diff, eExtendedRangeBrightnessChanged, other, currentHdrSdrRatio,
+ desiredHdrSdrRatio);
+ CHECK_DIFF(diff, eCachingHintChanged, other, cachingHint);
+ CHECK_DIFF(diff, eHdrMetadataChanged, other, hdrMetadata);
+ if (other.what & eSurfaceDamageRegionChanged &&
+ (!surfaceDamageRegion.hasSameRects(other.surfaceDamageRegion))) {
+ diff |= eSurfaceDamageRegionChanged;
+ }
+ CHECK_DIFF(diff, eApiChanged, other, api);
+ if (other.what & eSidebandStreamChanged) diff |= eSidebandStreamChanged;
+ CHECK_DIFF(diff, eApiChanged, other, api);
+ CHECK_DIFF(diff, eColorTransformChanged, other, colorTransform);
+ if (other.what & eHasListenerCallbacksChanged) diff |= eHasListenerCallbacksChanged;
+ if (other.what & eInputInfoChanged) diff |= eInputInfoChanged;
+ CHECK_DIFF2(diff, eBackgroundColorChanged, other, bgColor, bgColorDataspace);
+ if (other.what & eMetadataChanged) diff |= eMetadataChanged;
+ CHECK_DIFF(diff, eShadowRadiusChanged, other, shadowRadius);
+ CHECK_DIFF3(diff, eRenderBorderChanged, other, borderEnabled, borderWidth, borderColor);
+ CHECK_DIFF(diff, eDefaultFrameRateCompatibilityChanged, other, defaultFrameRateCompatibility);
+ CHECK_DIFF(diff, eFrameRateSelectionPriority, other, frameRateSelectionPriority);
+ CHECK_DIFF3(diff, eFrameRateChanged, other, frameRate, frameRateCompatibility,
+ changeFrameRateStrategy);
+ CHECK_DIFF(diff, eFixedTransformHintChanged, other, fixedTransformHint);
+ CHECK_DIFF(diff, eAutoRefreshChanged, other, autoRefresh);
+ CHECK_DIFF(diff, eTrustedOverlayChanged, other, isTrustedOverlay);
+ CHECK_DIFF(diff, eStretchChanged, other, stretchEffect);
+ CHECK_DIFF(diff, eBufferCropChanged, other, bufferCrop);
+ CHECK_DIFF(diff, eDestinationFrameChanged, other, destinationFrame);
+ if (other.what & eProducerDisconnect) diff |= eProducerDisconnect;
+ CHECK_DIFF(diff, eDropInputModeChanged, other, dropInputMode);
+ CHECK_DIFF(diff, eColorChanged, other, color.rgb);
+ CHECK_DIFF(diff, eColorSpaceAgnosticChanged, other, colorSpaceAgnostic);
+ CHECK_DIFF(diff, eDimmingEnabledChanged, other, dimmingEnabled);
+ return diff;
+}
+
bool layer_state_t::hasBufferChanges() const {
return what & layer_state_t::eBufferChanged;
}
bool layer_state_t::hasValidBuffer() const {
- return bufferData && (bufferData->buffer || bufferData->cachedBuffer.isValid());
+ return bufferData && (bufferData->hasBuffer() || bufferData->cachedBuffer.isValid());
}
status_t layer_state_t::matrix22_t::write(Parcel& output) const {
@@ -662,29 +814,44 @@ bool InputWindowCommands::merge(const InputWindowCommands& other) {
changes |= !other.focusRequests.empty();
focusRequests.insert(focusRequests.end(), std::make_move_iterator(other.focusRequests.begin()),
std::make_move_iterator(other.focusRequests.end()));
- changes |= other.syncInputWindows && !syncInputWindows;
- syncInputWindows |= other.syncInputWindows;
+ changes |= !other.windowInfosReportedListeners.empty();
+ windowInfosReportedListeners.insert(other.windowInfosReportedListeners.begin(),
+ other.windowInfosReportedListeners.end());
return changes;
}
bool InputWindowCommands::empty() const {
- return focusRequests.empty() && !syncInputWindows;
+ return focusRequests.empty() && windowInfosReportedListeners.empty();
}
void InputWindowCommands::clear() {
focusRequests.clear();
- syncInputWindows = false;
+ windowInfosReportedListeners.clear();
}
status_t InputWindowCommands::write(Parcel& output) const {
SAFE_PARCEL(output.writeParcelableVector, focusRequests);
- SAFE_PARCEL(output.writeBool, syncInputWindows);
+
+ SAFE_PARCEL(output.writeInt32, windowInfosReportedListeners.size());
+ for (const auto& listener : windowInfosReportedListeners) {
+ SAFE_PARCEL(output.writeStrongBinder, listener);
+ }
+
return NO_ERROR;
}
status_t InputWindowCommands::read(const Parcel& input) {
SAFE_PARCEL(input.readParcelableVector, &focusRequests);
- SAFE_PARCEL(input.readBool, &syncInputWindows);
+
+ int listenerSize = 0;
+ SAFE_PARCEL_READ_SIZE(input.readInt32, &listenerSize, input.dataSize());
+ windowInfosReportedListeners.reserve(listenerSize);
+ for (int i = 0; i < listenerSize; i++) {
+ sp<gui::IWindowInfosReportedListener> listener;
+ SAFE_PARCEL(input.readStrongBinder, &listener);
+ windowInfosReportedListeners.insert(listener);
+ }
+
return NO_ERROR;
}
@@ -730,6 +897,11 @@ status_t CaptureArgs::writeToParcel(Parcel* output) const {
SAFE_PARCEL(output->writeInt32, static_cast<int32_t>(dataspace));
SAFE_PARCEL(output->writeBool, allowProtected);
SAFE_PARCEL(output->writeBool, grayscale);
+ SAFE_PARCEL(output->writeInt32, excludeHandles.size());
+ for (auto& excludeHandle : excludeHandles) {
+ SAFE_PARCEL(output->writeStrongBinder, excludeHandle);
+ }
+ SAFE_PARCEL(output->writeBool, hintForSeamlessTransition);
return NO_ERROR;
}
@@ -746,6 +918,15 @@ status_t CaptureArgs::readFromParcel(const Parcel* input) {
dataspace = static_cast<ui::Dataspace>(value);
SAFE_PARCEL(input->readBool, &allowProtected);
SAFE_PARCEL(input->readBool, &grayscale);
+ int32_t numExcludeHandles = 0;
+ SAFE_PARCEL_READ_SIZE(input->readInt32, &numExcludeHandles, input->dataSize());
+ excludeHandles.reserve(numExcludeHandles);
+ for (int i = 0; i < numExcludeHandles; i++) {
+ sp<IBinder> binder;
+ SAFE_PARCEL(input->readStrongBinder, &binder);
+ excludeHandles.emplace(binder);
+ }
+ SAFE_PARCEL(input->readBool, &hintForSeamlessTransition);
return NO_ERROR;
}
@@ -773,10 +954,6 @@ status_t LayerCaptureArgs::writeToParcel(Parcel* output) const {
SAFE_PARCEL(CaptureArgs::writeToParcel, output);
SAFE_PARCEL(output->writeStrongBinder, layerHandle);
- SAFE_PARCEL(output->writeInt32, excludeHandles.size());
- for (auto el : excludeHandles) {
- SAFE_PARCEL(output->writeStrongBinder, el);
- }
SAFE_PARCEL(output->writeBool, childrenOnly);
return NO_ERROR;
}
@@ -786,15 +963,6 @@ status_t LayerCaptureArgs::readFromParcel(const Parcel* input) {
SAFE_PARCEL(input->readStrongBinder, &layerHandle);
- int32_t numExcludeHandles = 0;
- SAFE_PARCEL_READ_SIZE(input->readInt32, &numExcludeHandles, input->dataSize());
- excludeHandles.reserve(numExcludeHandles);
- for (int i = 0; i < numExcludeHandles; i++) {
- sp<IBinder> binder;
- SAFE_PARCEL(input->readStrongBinder, &binder);
- excludeHandles.emplace(binder);
- }
-
SAFE_PARCEL(input->readBool, &childrenOnly);
return NO_ERROR;
}
@@ -836,6 +1004,7 @@ status_t BufferData::writeToParcel(Parcel* output) const {
SAFE_PARCEL(output->writeUint64, cachedBuffer.id);
SAFE_PARCEL(output->writeBool, hasBarrier);
SAFE_PARCEL(output->writeUint64, barrierFrameNumber);
+ SAFE_PARCEL(output->writeUint32, producerId);
return NO_ERROR;
}
@@ -874,8 +1043,25 @@ status_t BufferData::readFromParcel(const Parcel* input) {
SAFE_PARCEL(input->readBool, &hasBarrier);
SAFE_PARCEL(input->readUint64, &barrierFrameNumber);
+ SAFE_PARCEL(input->readUint32, &producerId);
return NO_ERROR;
}
+status_t TrustedPresentationListener::writeToParcel(Parcel* parcel) const {
+ SAFE_PARCEL(parcel->writeStrongBinder, callbackInterface);
+ SAFE_PARCEL(parcel->writeInt32, callbackId);
+ return NO_ERROR;
+}
+
+status_t TrustedPresentationListener::readFromParcel(const Parcel* parcel) {
+ sp<IBinder> tmpBinder = nullptr;
+ SAFE_PARCEL(parcel->readNullableStrongBinder, &tmpBinder);
+ if (tmpBinder) {
+ callbackInterface = checked_interface_cast<ITransactionCompletedListener>(tmpBinder);
+ }
+ SAFE_PARCEL(parcel->readInt32, &callbackId);
+ return NO_ERROR;
+}
+
}; // namespace android
diff --git a/libs/gui/LayerStatePermissions.cpp b/libs/gui/LayerStatePermissions.cpp
new file mode 100644
index 0000000000..28697ca953
--- /dev/null
+++ b/libs/gui/LayerStatePermissions.cpp
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <binder/IPCThreadState.h>
+#include <gui/LayerStatePermissions.h>
+#include <private/android_filesystem_config.h>
+#ifndef __ANDROID_VNDK__
+#include <binder/PermissionCache.h>
+#endif // __ANDROID_VNDK__
+#include <gui/LayerState.h>
+
+namespace android {
+std::unordered_map<std::string, int> LayerStatePermissions::mPermissionMap = {
+ // If caller has ACCESS_SURFACE_FLINGER, they automatically get ROTATE_SURFACE_FLINGER
+ // permission, as well
+ {"android.permission.ACCESS_SURFACE_FLINGER",
+ layer_state_t::Permission::ACCESS_SURFACE_FLINGER |
+ layer_state_t::Permission::ROTATE_SURFACE_FLINGER},
+ {"android.permission.ROTATE_SURFACE_FLINGER",
+ layer_state_t::Permission::ROTATE_SURFACE_FLINGER},
+ {"android.permission.INTERNAL_SYSTEM_WINDOW",
+ layer_state_t::Permission::INTERNAL_SYSTEM_WINDOW},
+};
+
+static bool callingThreadHasPermission(const std::string& permission __attribute__((unused)),
+ int pid __attribute__((unused)),
+ int uid __attribute__((unused))) {
+#ifndef __ANDROID_VNDK__
+ return uid == AID_GRAPHICS || uid == AID_SYSTEM ||
+ PermissionCache::checkPermission(String16(permission.c_str()), pid, uid);
+#endif // __ANDROID_VNDK__
+ return false;
+}
+
+uint32_t LayerStatePermissions::getTransactionPermissions(int pid, int uid) {
+ uint32_t permissions = 0;
+ for (auto [permissionName, permissionVal] : mPermissionMap) {
+ if (callingThreadHasPermission(permissionName, pid, uid)) {
+ permissions |= permissionVal;
+ }
+ }
+
+ return permissions;
+}
+} // namespace android
diff --git a/libs/gui/ScreenCaptureResults.cpp b/libs/gui/ScreenCaptureResults.cpp
index fe387064bc..601a5f9b33 100644
--- a/libs/gui/ScreenCaptureResults.cpp
+++ b/libs/gui/ScreenCaptureResults.cpp
@@ -17,6 +17,7 @@
#include <gui/ScreenCaptureResults.h>
#include <private/gui/ParcelUtils.h>
+#include <ui/FenceResult.h>
namespace android::gui {
@@ -28,17 +29,17 @@ status_t ScreenCaptureResults::writeToParcel(android::Parcel* parcel) const {
SAFE_PARCEL(parcel->writeBool, false);
}
- if (fence != Fence::NO_FENCE) {
+ if (fenceResult.ok() && fenceResult.value() != Fence::NO_FENCE) {
SAFE_PARCEL(parcel->writeBool, true);
- SAFE_PARCEL(parcel->write, *fence);
+ SAFE_PARCEL(parcel->write, *fenceResult.value());
} else {
SAFE_PARCEL(parcel->writeBool, false);
+ SAFE_PARCEL(parcel->writeInt32, fenceStatus(fenceResult));
}
SAFE_PARCEL(parcel->writeBool, capturedSecureLayers);
SAFE_PARCEL(parcel->writeBool, capturedHdrLayers);
SAFE_PARCEL(parcel->writeUint32, static_cast<uint32_t>(capturedDataspace));
- SAFE_PARCEL(parcel->writeInt32, result);
return NO_ERROR;
}
@@ -53,8 +54,13 @@ status_t ScreenCaptureResults::readFromParcel(const android::Parcel* parcel) {
bool hasFence;
SAFE_PARCEL(parcel->readBool, &hasFence);
if (hasFence) {
- fence = new Fence();
- SAFE_PARCEL(parcel->read, *fence);
+ fenceResult = sp<Fence>::make();
+ SAFE_PARCEL(parcel->read, *fenceResult.value());
+ } else {
+ status_t status;
+ SAFE_PARCEL(parcel->readInt32, &status);
+ fenceResult = status == NO_ERROR ? FenceResult(Fence::NO_FENCE)
+ : FenceResult(base::unexpected(status));
}
SAFE_PARCEL(parcel->readBool, &capturedSecureLayers);
@@ -62,7 +68,6 @@ status_t ScreenCaptureResults::readFromParcel(const android::Parcel* parcel) {
uint32_t dataspace = 0;
SAFE_PARCEL(parcel->readUint32, &dataspace);
capturedDataspace = static_cast<ui::Dataspace>(dataspace);
- SAFE_PARCEL(parcel->readInt32, &result);
return NO_ERROR;
}
diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp
index 16edfd4267..ed691006e9 100644
--- a/libs/gui/Surface.cpp
+++ b/libs/gui/Surface.cpp
@@ -30,15 +30,18 @@
#include <android/gui/DisplayStatInfo.h>
#include <android/native_window.h>
+#include <gui/FenceMonitor.h>
+#include <gui/TraceUtils.h>
#include <utils/Log.h>
-#include <utils/Trace.h>
#include <utils/NativeHandle.h>
+#include <utils/Trace.h>
#include <ui/DynamicDisplayInfo.h>
#include <ui/Fence.h>
#include <ui/GraphicBuffer.h>
#include <ui/Region.h>
+#include <gui/AidlStatusUtil.h>
#include <gui/BufferItem.h>
#include <gui/IProducerListener.h>
@@ -49,10 +52,17 @@
namespace android {
+using gui::aidl_utils::statusTFromBinderStatus;
using ui::Dataspace;
namespace {
+enum {
+ // moved from nativewindow/include/system/window.h, to be removed
+ NATIVE_WINDOW_GET_WIDE_COLOR_SUPPORT = 28,
+ NATIVE_WINDOW_GET_HDR_SUPPORT = 29,
+};
+
bool isInterceptorRegistrationOp(int op) {
return op == NATIVE_WINDOW_SET_CANCEL_INTERCEPTOR ||
op == NATIVE_WINDOW_SET_DEQUEUE_INTERCEPTOR ||
@@ -182,7 +192,7 @@ status_t Surface::getDisplayRefreshCycleDuration(nsecs_t* outRefreshDuration) {
gui::DisplayStatInfo stats;
binder::Status status = composerServiceAIDL()->getDisplayStats(nullptr, &stats);
if (!status.isOk()) {
- return status.transactionError();
+ return statusTFromBinderStatus(status);
}
*outRefreshDuration = stats.vsyncPeriod;
@@ -345,33 +355,25 @@ status_t Surface::getFrameTimestamps(uint64_t frameNumber,
return NO_ERROR;
}
+// Deprecated(b/242763577): to be removed, this method should not be used
+// The reason this method still exists here is to support compiled vndk
+// Surface support should not be tied to the display
+// Return true since most displays should have this support
status_t Surface::getWideColorSupport(bool* supported) {
ATRACE_CALL();
- const sp<IBinder> display = ComposerServiceAIDL::getInstance().getInternalDisplayToken();
- if (display == nullptr) {
- return NAME_NOT_FOUND;
- }
-
- *supported = false;
- binder::Status status = composerServiceAIDL()->isWideColorDisplay(display, supported);
- return status.transactionError();
+ *supported = true;
+ return NO_ERROR;
}
+// Deprecated(b/242763577): to be removed, this method should not be used
+// The reason this method still exists here is to support compiled vndk
+// Surface support should not be tied to the display
+// Return true since most displays should have this support
status_t Surface::getHdrSupport(bool* supported) {
ATRACE_CALL();
- const sp<IBinder> display = ComposerServiceAIDL::getInstance().getInternalDisplayToken();
- if (display == nullptr) {
- return NAME_NOT_FOUND;
- }
-
- ui::DynamicDisplayInfo info;
- if (status_t err = composerService()->getDynamicDisplayInfo(display, &info); err != NO_ERROR) {
- return err;
- }
-
- *supported = !info.hdrCapabilities.getSupportedHdrTypes().empty();
+ *supported = true;
return NO_ERROR;
}
@@ -544,82 +546,6 @@ int Surface::setSwapInterval(int interval) {
return NO_ERROR;
}
-class FenceMonitor {
-public:
- explicit FenceMonitor(const char* name) : mName(name), mFencesQueued(0), mFencesSignaled(0) {
- std::thread thread(&FenceMonitor::loop, this);
- pthread_setname_np(thread.native_handle(), mName);
- thread.detach();
- }
-
- void queueFence(const sp<Fence>& fence) {
- char message[64];
-
- std::lock_guard<std::mutex> lock(mMutex);
- if (fence->getSignalTime() != Fence::SIGNAL_TIME_PENDING) {
- snprintf(message, sizeof(message), "%s fence %u has signaled", mName, mFencesQueued);
- ATRACE_NAME(message);
- // Need an increment on both to make the trace number correct.
- mFencesQueued++;
- mFencesSignaled++;
- return;
- }
- snprintf(message, sizeof(message), "Trace %s fence %u", mName, mFencesQueued);
- ATRACE_NAME(message);
-
- mQueue.push_back(fence);
- mCondition.notify_one();
- mFencesQueued++;
- ATRACE_INT(mName, int32_t(mQueue.size()));
- }
-
-private:
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wmissing-noreturn"
- void loop() {
- while (true) {
- threadLoop();
- }
- }
-#pragma clang diagnostic pop
-
- void threadLoop() {
- sp<Fence> fence;
- uint32_t fenceNum;
- {
- std::unique_lock<std::mutex> lock(mMutex);
- while (mQueue.empty()) {
- mCondition.wait(lock);
- }
- fence = mQueue[0];
- fenceNum = mFencesSignaled;
- }
- {
- char message[64];
- snprintf(message, sizeof(message), "waiting for %s %u", mName, fenceNum);
- ATRACE_NAME(message);
-
- status_t result = fence->waitForever(message);
- if (result != OK) {
- ALOGE("Error waiting for fence: %d", result);
- }
- }
- {
- std::lock_guard<std::mutex> lock(mMutex);
- mQueue.pop_front();
- mFencesSignaled++;
- ATRACE_INT(mName, int32_t(mQueue.size()));
- }
- }
-
- const char* mName;
- uint32_t mFencesQueued;
- uint32_t mFencesSignaled;
- std::deque<sp<Fence>> mQueue;
- std::condition_variable mCondition;
- std::mutex mMutex;
-};
-
void Surface::getDequeueBufferInputLocked(
IGraphicBufferProducer::DequeueBufferInput* dequeueInput) {
LOG_ALWAYS_FATAL_IF(dequeueInput == nullptr, "input is null");
@@ -634,7 +560,7 @@ void Surface::getDequeueBufferInputLocked(
}
int Surface::dequeueBuffer(android_native_buffer_t** buffer, int* fenceFd) {
- ATRACE_CALL();
+ ATRACE_FORMAT("dequeueBuffer - %s", getDebugName());
ALOGV("Surface::dequeueBuffer");
IGraphicBufferProducer::DequeueBufferInput dqInput;
@@ -693,7 +619,7 @@ int Surface::dequeueBuffer(android_native_buffer_t** buffer, int* fenceFd) {
ALOGE_IF(fence == nullptr, "Surface::dequeueBuffer: received null Fence! buf=%d", buf);
if (CC_UNLIKELY(atrace_is_tag_enabled(ATRACE_TAG_GRAPHICS))) {
- static FenceMonitor hwcReleaseThread("HWC release");
+ static gui::FenceMonitor hwcReleaseThread("HWC release");
hwcReleaseThread.queueFence(fence);
}
@@ -892,7 +818,7 @@ int Surface::dequeueBuffers(std::vector<BatchBuffer>* buffers) {
sp<GraphicBuffer>& gbuf(mSlots[slot].buffer);
if (CC_UNLIKELY(atrace_is_tag_enabled(ATRACE_TAG_GRAPHICS))) {
- static FenceMonitor hwcReleaseThread("HWC release");
+ static gui::FenceMonitor hwcReleaseThread("HWC release");
hwcReleaseThread.queueFence(output.fence);
}
@@ -1162,7 +1088,7 @@ void Surface::onBufferQueuedLocked(int slot, sp<Fence> fence,
mQueueBufferCondition.broadcast();
if (CC_UNLIKELY(atrace_is_tag_enabled(ATRACE_TAG_GRAPHICS))) {
- static FenceMonitor gpuCompletionThread("GPU completion");
+ static gui::FenceMonitor gpuCompletionThread("GPU completion");
gpuCompletionThread.queueFence(fence);
}
}
@@ -1263,10 +1189,10 @@ void Surface::querySupportedTimestampsLocked() const {
mQueriedSupportedTimestamps = true;
std::vector<FrameEvent> supportedFrameTimestamps;
- status_t err = composerService()->getSupportedFrameTimestamps(
- &supportedFrameTimestamps);
+ binder::Status status =
+ composerServiceAIDL()->getSupportedFrameTimestamps(&supportedFrameTimestamps);
- if (err != NO_ERROR) {
+ if (!status.isOk()) {
return;
}
@@ -1294,15 +1220,12 @@ int Surface::query(int what, int* value) const {
if (err == NO_ERROR) {
return NO_ERROR;
}
- sp<ISurfaceComposer> surfaceComposer = composerService();
+ sp<gui::ISurfaceComposer> surfaceComposer = composerServiceAIDL();
if (surfaceComposer == nullptr) {
return -EPERM; // likely permissions error
}
- if (surfaceComposer->authenticateSurfaceTexture(mGraphicBufferProducer)) {
- *value = 1;
- } else {
- *value = 0;
- }
+ // ISurfaceComposer no longer supports authenticateSurfaceTexture
+ *value = 0;
return NO_ERROR;
}
case NATIVE_WINDOW_CONCRETE_TYPE:
@@ -1873,9 +1796,15 @@ int Surface::dispatchSetFrameTimelineInfo(va_list args) {
auto frameTimelineVsyncId = static_cast<int64_t>(va_arg(args, int64_t));
auto inputEventId = static_cast<int32_t>(va_arg(args, int32_t));
auto startTimeNanos = static_cast<int64_t>(va_arg(args, int64_t));
+ auto useForRefreshRateSelection = static_cast<bool>(va_arg(args, int32_t));
ALOGV("Surface::%s", __func__);
- return setFrameTimelineInfo(frameNumber, {frameTimelineVsyncId, inputEventId, startTimeNanos});
+ FrameTimelineInfo ftlInfo;
+ ftlInfo.vsyncId = frameTimelineVsyncId;
+ ftlInfo.inputEventId = inputEventId;
+ ftlInfo.startTimeNanos = startTimeNanos;
+ ftlInfo.useForRefreshRateSelection = useForRefreshRateSelection;
+ return setFrameTimelineInfo(frameNumber, ftlInfo);
}
bool Surface::transformToDisplayInverse() const {
@@ -2635,23 +2564,19 @@ void Surface::ProducerListenerProxy::onBuffersDiscarded(const std::vector<int32_
mSurfaceListener->onBuffersDiscarded(discardedBufs);
}
-status_t Surface::setFrameRate(float frameRate, int8_t compatibility,
- int8_t changeFrameRateStrategy) {
- ATRACE_CALL();
- ALOGV("Surface::setFrameRate");
-
- if (!ValidateFrameRate(frameRate, compatibility, changeFrameRateStrategy,
- "Surface::setFrameRate")) {
- return BAD_VALUE;
- }
-
- return composerService()->setFrameRate(mGraphicBufferProducer, frameRate, compatibility,
- changeFrameRateStrategy);
+[[deprecated]] status_t Surface::setFrameRate(float /*frameRate*/, int8_t /*compatibility*/,
+ int8_t /*changeFrameRateStrategy*/) {
+ ALOGI("Surface::setFrameRate is deprecated, setFrameRate hint is dropped as destination is not "
+ "SurfaceFlinger");
+ // ISurfaceComposer no longer supports setFrameRate, we will return NO_ERROR when the api is
+ // called to avoid apps crashing, as BAD_VALUE can generate fatal exception in apps.
+ return NO_ERROR;
}
status_t Surface::setFrameTimelineInfo(uint64_t /*frameNumber*/,
- const FrameTimelineInfo& frameTimelineInfo) {
- return composerService()->setFrameTimelineInfo(mGraphicBufferProducer, frameTimelineInfo);
+ const FrameTimelineInfo& /*frameTimelineInfo*/) {
+ // ISurfaceComposer no longer supports setFrameTimelineInfo
+ return BAD_VALUE;
}
sp<IBinder> Surface::getSurfaceControlHandle() const {
@@ -2664,4 +2589,12 @@ void Surface::destroy() {
mSurfaceControlHandle = nullptr;
}
+const char* Surface::getDebugName() {
+ std::unique_lock lock{mNameMutex};
+ if (mName.empty()) {
+ mName = getConsumerName();
+ }
+ return mName.c_str();
+}
+
}; // namespace android
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 6d44f1079c..8a1f7c6238 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -16,11 +16,17 @@
#define LOG_TAG "SurfaceComposerClient"
+#include <semaphore.h>
#include <stdint.h>
#include <sys/types.h>
+#include <android/gui/BnWindowInfosReportedListener.h>
#include <android/gui/DisplayState.h>
+#include <android/gui/ISurfaceComposerClient.h>
#include <android/gui/IWindowInfosListener.h>
+#include <android/gui/TrustedPresentationThresholds.h>
+#include <android/os/IInputConstants.h>
+#include <gui/TraceUtils.h>
#include <utils/Errors.h>
#include <utils/Log.h>
#include <utils/SortedVector.h>
@@ -33,11 +39,11 @@
#include <system/graphics.h>
+#include <gui/AidlStatusUtil.h>
#include <gui/BufferItemConsumer.h>
#include <gui/CpuConsumer.h>
#include <gui/IGraphicBufferProducer.h>
#include <gui/ISurfaceComposer.h>
-#include <gui/ISurfaceComposerClient.h>
#include <gui/LayerState.h>
#include <gui/Surface.h>
#include <gui/SurfaceComposerClient.h>
@@ -47,6 +53,8 @@
#include <ui/DisplayState.h>
#include <ui/DynamicDisplayInfo.h>
+#include <android-base/thread_annotations.h>
+#include <gui/LayerStatePermissions.h>
#include <private/gui/ComposerService.h>
#include <private/gui/ComposerServiceAIDL.h>
@@ -58,9 +66,11 @@ namespace android {
using aidl::android::hardware::graphics::common::DisplayDecorationSupport;
using gui::FocusRequest;
using gui::IRegionSamplingListener;
+using gui::TrustedPresentationThresholds;
using gui::WindowInfo;
using gui::WindowInfoHandle;
using gui::WindowInfosListener;
+using gui::aidl_utils::statusTFromBinderStatus;
using ui::ColorMode;
// ---------------------------------------------------------------------------
@@ -73,6 +83,8 @@ std::atomic<uint32_t> idCounter = 0;
int64_t generateId() {
return (((int64_t)getpid()) << 32) | ++idCounter;
}
+
+void emptyCallback(nsecs_t, const sp<Fence>&, const std::vector<SurfaceControlStats>&) {}
} // namespace
ComposerService::ComposerService()
@@ -111,7 +123,6 @@ bool ComposerService::connectLocked() {
if (instance.mComposerService == nullptr) {
if (ComposerService::getInstance().connectLocked()) {
ALOGD("ComposerService reconnected");
- WindowInfosListenerReporter::getInstance()->reconnect(instance.mComposerService);
}
}
return instance.mComposerService;
@@ -159,6 +170,7 @@ bool ComposerServiceAIDL::connectLocked() {
if (instance.mComposerService == nullptr) {
if (ComposerServiceAIDL::getInstance().connectLocked()) {
ALOGD("ComposerServiceAIDL reconnected");
+ WindowInfosListenerReporter::getInstance()->reconnect(instance.mComposerService);
}
}
return instance.mComposerService;
@@ -240,6 +252,14 @@ CallbackId TransactionCompletedListener::addCallbackFunction(
surfaceControls,
CallbackId::Type callbackType) {
std::lock_guard<std::mutex> lock(mMutex);
+ return addCallbackFunctionLocked(callbackFunction, surfaceControls, callbackType);
+}
+
+CallbackId TransactionCompletedListener::addCallbackFunctionLocked(
+ const TransactionCompletedCallback& callbackFunction,
+ const std::unordered_set<sp<SurfaceControl>, SurfaceComposerClient::SCHash>&
+ surfaceControls,
+ CallbackId::Type callbackType) {
startListeningLocked();
CallbackId callbackId(getNextIdLocked(), callbackType);
@@ -248,6 +268,11 @@ CallbackId TransactionCompletedListener::addCallbackFunction(
for (const auto& surfaceControl : surfaceControls) {
callbackSurfaceControls[surfaceControl->getHandle()] = surfaceControl;
+
+ if (callbackType == CallbackId::Type::ON_COMPLETE &&
+ mJankListeners.count(surfaceControl->getLayerId()) != 0) {
+ callbackId.includeJankData = true;
+ }
}
return callbackId;
@@ -296,15 +321,26 @@ void TransactionCompletedListener::removeSurfaceStatsListener(void* context, voi
}
void TransactionCompletedListener::addSurfaceControlToCallbacks(
- const sp<SurfaceControl>& surfaceControl,
- const std::unordered_set<CallbackId, CallbackIdHash>& callbackIds) {
+ SurfaceComposerClient::CallbackInfo& callbackInfo,
+ const sp<SurfaceControl>& surfaceControl) {
std::lock_guard<std::mutex> lock(mMutex);
- for (auto callbackId : callbackIds) {
+ bool includingJankData = false;
+ for (auto callbackId : callbackInfo.callbackIds) {
mCallbacks[callbackId].surfaceControls.emplace(std::piecewise_construct,
std::forward_as_tuple(
surfaceControl->getHandle()),
std::forward_as_tuple(surfaceControl));
+ includingJankData = includingJankData || callbackId.includeJankData;
+ }
+
+ // If no registered callback is requesting jank data, but there is a jank listener registered
+ // on the new surface control, add a synthetic callback that requests the jank data.
+ if (!includingJankData && mJankListeners.count(surfaceControl->getLayerId()) != 0) {
+ CallbackId callbackId =
+ addCallbackFunctionLocked(&emptyCallback, callbackInfo.surfaceControls,
+ CallbackId::Type::ON_COMPLETE);
+ callbackInfo.callbackIds.emplace(callbackId);
}
}
@@ -380,10 +416,11 @@ void TransactionCompletedListener::onTransactionCompleted(ListenerStats listener
surfaceStats.previousReleaseFence, surfaceStats.transformHint,
surfaceStats.eventStats,
surfaceStats.currentMaxAcquiredBufferCount);
- if (callbacksMap[callbackId].surfaceControls[surfaceStats.surfaceControl]) {
+ if (callbacksMap[callbackId].surfaceControls[surfaceStats.surfaceControl] &&
+ surfaceStats.transformHint.has_value()) {
callbacksMap[callbackId]
.surfaceControls[surfaceStats.surfaceControl]
- ->setTransformHint(surfaceStats.transformHint);
+ ->setTransformHint(*surfaceStats.transformHint);
}
// If there is buffer id set, we look up any pending client release buffer callbacks
// and call them. This is a performance optimization when we have a transaction
@@ -449,23 +486,24 @@ void TransactionCompletedListener::onTransactionCompleted(ListenerStats listener
}
}
-void TransactionCompletedListener::onTransactionQueueStalled() {
- std::unordered_map<void*, std::function<void()>> callbackCopy;
- {
- std::scoped_lock<std::mutex> lock(mMutex);
- callbackCopy = mQueueStallListeners;
- }
- for (auto const& it : callbackCopy) {
- it.second();
- }
+void TransactionCompletedListener::onTransactionQueueStalled(const String8& reason) {
+ std::unordered_map<void*, std::function<void(const std::string&)>> callbackCopy;
+ {
+ std::scoped_lock<std::mutex> lock(mMutex);
+ callbackCopy = mQueueStallListeners;
+ }
+ for (auto const& it : callbackCopy) {
+ it.second(reason.c_str());
+ }
}
-void TransactionCompletedListener::addQueueStallListener(std::function<void()> stallListener,
- void* id) {
+void TransactionCompletedListener::addQueueStallListener(
+ std::function<void(const std::string&)> stallListener, void* id) {
std::scoped_lock<std::mutex> lock(mMutex);
mQueueStallListeners[id] = stallListener;
}
-void TransactionCompletedListener::removeQueueStallListener(void *id) {
+
+void TransactionCompletedListener::removeQueueStallListener(void* id) {
std::scoped_lock<std::mutex> lock(mMutex);
mQueueStallListeners.erase(id);
}
@@ -510,6 +548,45 @@ void TransactionCompletedListener::removeReleaseBufferCallback(
}
}
+SurfaceComposerClient::PresentationCallbackRAII::PresentationCallbackRAII(
+ TransactionCompletedListener* tcl, int id) {
+ mTcl = tcl;
+ mId = id;
+}
+
+SurfaceComposerClient::PresentationCallbackRAII::~PresentationCallbackRAII() {
+ mTcl->clearTrustedPresentationCallback(mId);
+}
+
+sp<SurfaceComposerClient::PresentationCallbackRAII>
+TransactionCompletedListener::addTrustedPresentationCallback(TrustedPresentationCallback tpc,
+ int id, void* context) {
+ std::scoped_lock<std::mutex> lock(mMutex);
+ mTrustedPresentationCallbacks[id] =
+ std::tuple<TrustedPresentationCallback, void*>(tpc, context);
+ return new SurfaceComposerClient::PresentationCallbackRAII(this, id);
+}
+
+void TransactionCompletedListener::clearTrustedPresentationCallback(int id) {
+ std::scoped_lock<std::mutex> lock(mMutex);
+ mTrustedPresentationCallbacks.erase(id);
+}
+
+void TransactionCompletedListener::onTrustedPresentationChanged(int id,
+ bool presentedWithinThresholds) {
+ TrustedPresentationCallback tpc;
+ void* context;
+ {
+ std::scoped_lock<std::mutex> lock(mMutex);
+ auto it = mTrustedPresentationCallbacks.find(id);
+ if (it == mTrustedPresentationCallbacks.end()) {
+ return;
+ }
+ std::tie(tpc, context) = it->second;
+ }
+ tpc(context, presentedWithinThresholds);
+}
+
// ---------------------------------------------------------------------------
void removeDeadBufferCallback(void* /*context*/, uint64_t graphicBufferId);
@@ -557,11 +634,13 @@ public:
return NO_ERROR;
}
- uint64_t cache(const sp<GraphicBuffer>& buffer) {
+ uint64_t cache(const sp<GraphicBuffer>& buffer,
+ std::optional<client_cache_t>& outUncacheBuffer) {
std::lock_guard<std::mutex> lock(mMutex);
if (mBuffers.size() >= BUFFER_CACHE_MAX_SIZE) {
- evictLeastRecentlyUsedBuffer();
+ outUncacheBuffer = findLeastRecentlyUsedBuffer();
+ mBuffers.erase(outUncacheBuffer->id);
}
buffer->addDeathCallback(removeDeadBufferCallback, nullptr);
@@ -572,16 +651,13 @@ public:
void uncache(uint64_t cacheId) {
std::lock_guard<std::mutex> lock(mMutex);
- uncacheLocked(cacheId);
- }
-
- void uncacheLocked(uint64_t cacheId) REQUIRES(mMutex) {
- mBuffers.erase(cacheId);
- SurfaceComposerClient::doUncacheBufferTransaction(cacheId);
+ if (mBuffers.erase(cacheId)) {
+ SurfaceComposerClient::doUncacheBufferTransaction(cacheId);
+ }
}
private:
- void evictLeastRecentlyUsedBuffer() REQUIRES(mMutex) {
+ client_cache_t findLeastRecentlyUsedBuffer() REQUIRES(mMutex) {
auto itr = mBuffers.begin();
uint64_t minCounter = itr->second;
auto minBuffer = itr;
@@ -595,7 +671,8 @@ private:
}
itr++;
}
- uncacheLocked(minBuffer->first);
+
+ return {.token = getToken(), .id = minBuffer->first};
}
uint64_t getCounter() REQUIRES(mMutex) {
@@ -625,12 +702,11 @@ SurfaceComposerClient::Transaction::Transaction() {
SurfaceComposerClient::Transaction::Transaction(const Transaction& other)
: mId(other.mId),
- mForceSynchronous(other.mForceSynchronous),
mTransactionNestCount(other.mTransactionNestCount),
mAnimation(other.mAnimation),
mEarlyWakeupStart(other.mEarlyWakeupStart),
mEarlyWakeupEnd(other.mEarlyWakeupEnd),
- mContainsBuffer(other.mContainsBuffer),
+ mMayContainBuffer(other.mMayContainBuffer),
mDesiredPresentTime(other.mDesiredPresentTime),
mIsAutoTimestamp(other.mIsAutoTimestamp),
mFrameTimelineInfo(other.mFrameTimelineInfo),
@@ -641,11 +717,16 @@ SurfaceComposerClient::Transaction::Transaction(const Transaction& other)
mListenerCallbacks = other.mListenerCallbacks;
}
-void SurfaceComposerClient::Transaction::sanitize() {
+void SurfaceComposerClient::Transaction::sanitize(int pid, int uid) {
+ uint32_t permissions = LayerStatePermissions::getTransactionPermissions(pid, uid);
for (auto & [handle, composerState] : mComposerStates) {
- composerState.state.sanitize(0 /* permissionMask */);
+ composerState.state.sanitize(permissions);
+ }
+ if (!mInputWindowCommands.empty() &&
+ (permissions & layer_state_t::Permission::ACCESS_SURFACE_FLINGER) == 0) {
+ ALOGE("Only privileged callers are allowed to send input commands.");
+ mInputWindowCommands.clear();
}
- mInputWindowCommands.clear();
}
std::unique_ptr<SurfaceComposerClient::Transaction>
@@ -659,16 +740,15 @@ SurfaceComposerClient::Transaction::createFromParcel(const Parcel* parcel) {
status_t SurfaceComposerClient::Transaction::readFromParcel(const Parcel* parcel) {
- const uint32_t forceSynchronous = parcel->readUint32();
+ const uint64_t transactionId = parcel->readUint64();
const uint32_t transactionNestCount = parcel->readUint32();
const bool animation = parcel->readBool();
const bool earlyWakeupStart = parcel->readBool();
const bool earlyWakeupEnd = parcel->readBool();
- const bool containsBuffer = parcel->readBool();
const int64_t desiredPresentTime = parcel->readInt64();
const bool isAutoTimestamp = parcel->readBool();
FrameTimelineInfo frameTimelineInfo;
- SAFE_PARCEL(frameTimelineInfo.read, *parcel);
+ frameTimelineInfo.readFromParcel(parcel);
sp<IBinder> applyToken;
parcel->readNullableStrongBinder(&applyToken);
@@ -735,13 +815,33 @@ status_t SurfaceComposerClient::Transaction::readFromParcel(const Parcel* parcel
InputWindowCommands inputWindowCommands;
inputWindowCommands.read(*parcel);
+ count = static_cast<size_t>(parcel->readUint32());
+ if (count > parcel->dataSize()) {
+ return BAD_VALUE;
+ }
+ std::vector<client_cache_t> uncacheBuffers(count);
+ for (size_t i = 0; i < count; i++) {
+ sp<IBinder> tmpBinder;
+ SAFE_PARCEL(parcel->readStrongBinder, &tmpBinder);
+ uncacheBuffers[i].token = tmpBinder;
+ SAFE_PARCEL(parcel->readUint64, &uncacheBuffers[i].id);
+ }
+
+ count = static_cast<size_t>(parcel->readUint32());
+ if (count > parcel->dataSize()) {
+ return BAD_VALUE;
+ }
+ std::vector<uint64_t> mergedTransactionIds(count);
+ for (size_t i = 0; i < count; i++) {
+ SAFE_PARCEL(parcel->readUint64, &mergedTransactionIds[i]);
+ }
+
// Parsing was successful. Update the object.
- mForceSynchronous = forceSynchronous;
+ mId = transactionId;
mTransactionNestCount = transactionNestCount;
mAnimation = animation;
mEarlyWakeupStart = earlyWakeupStart;
mEarlyWakeupEnd = earlyWakeupEnd;
- mContainsBuffer = containsBuffer;
mDesiredPresentTime = desiredPresentTime;
mIsAutoTimestamp = isAutoTimestamp;
mFrameTimelineInfo = frameTimelineInfo;
@@ -750,6 +850,8 @@ status_t SurfaceComposerClient::Transaction::readFromParcel(const Parcel* parcel
mComposerStates = composerStates;
mInputWindowCommands = inputWindowCommands;
mApplyToken = applyToken;
+ mUncacheBuffers = std::move(uncacheBuffers);
+ mMergedTransactionIds = std::move(mergedTransactionIds);
return NO_ERROR;
}
@@ -767,15 +869,14 @@ status_t SurfaceComposerClient::Transaction::writeToParcel(Parcel* parcel) const
const_cast<SurfaceComposerClient::Transaction*>(this)->cacheBuffers();
- parcel->writeUint32(mForceSynchronous);
+ parcel->writeUint64(mId);
parcel->writeUint32(mTransactionNestCount);
parcel->writeBool(mAnimation);
parcel->writeBool(mEarlyWakeupStart);
parcel->writeBool(mEarlyWakeupEnd);
- parcel->writeBool(mContainsBuffer);
parcel->writeInt64(mDesiredPresentTime);
parcel->writeBool(mIsAutoTimestamp);
- SAFE_PARCEL(mFrameTimelineInfo.write, *parcel);
+ mFrameTimelineInfo.writeToParcel(parcel);
parcel->writeStrongBinder(mApplyToken);
parcel->writeUint32(static_cast<uint32_t>(mDisplayStates.size()));
for (auto const& displayState : mDisplayStates) {
@@ -802,11 +903,23 @@ status_t SurfaceComposerClient::Transaction::writeToParcel(Parcel* parcel) const
}
mInputWindowCommands.write(*parcel);
+
+ SAFE_PARCEL(parcel->writeUint32, static_cast<uint32_t>(mUncacheBuffers.size()));
+ for (const client_cache_t& uncacheBuffer : mUncacheBuffers) {
+ SAFE_PARCEL(parcel->writeStrongBinder, uncacheBuffer.token.promote());
+ SAFE_PARCEL(parcel->writeUint64, uncacheBuffer.id);
+ }
+
+ SAFE_PARCEL(parcel->writeUint32, static_cast<uint32_t>(mMergedTransactionIds.size()));
+ for (auto mergedTransactionId : mMergedTransactionIds) {
+ SAFE_PARCEL(parcel->writeUint64, mergedTransactionId);
+ }
+
return NO_ERROR;
}
void SurfaceComposerClient::Transaction::releaseBufferIfOverwriting(const layer_state_t& state) {
- if (!(state.what & layer_state_t::eBufferChanged)) {
+ if (!(state.what & layer_state_t::eBufferChanged) || !state.bufferData->hasBuffer()) {
return;
}
@@ -826,6 +939,22 @@ void SurfaceComposerClient::Transaction::releaseBufferIfOverwriting(const layer_
}
SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::merge(Transaction&& other) {
+ while (mMergedTransactionIds.size() + other.mMergedTransactionIds.size() >
+ MAX_MERGE_HISTORY_LENGTH - 1 &&
+ mMergedTransactionIds.size() > 0) {
+ mMergedTransactionIds.pop_back();
+ }
+ if (other.mMergedTransactionIds.size() == MAX_MERGE_HISTORY_LENGTH) {
+ mMergedTransactionIds.insert(mMergedTransactionIds.begin(),
+ other.mMergedTransactionIds.begin(),
+ other.mMergedTransactionIds.end() - 1);
+ } else if (other.mMergedTransactionIds.size() > 0u) {
+ mMergedTransactionIds.insert(mMergedTransactionIds.begin(),
+ other.mMergedTransactionIds.begin(),
+ other.mMergedTransactionIds.end());
+ }
+ mMergedTransactionIds.insert(mMergedTransactionIds.begin(), other.mId);
+
for (auto const& [handle, composerState] : other.mComposerStates) {
if (mComposerStates.count(handle) == 0) {
mComposerStates[handle] = composerState;
@@ -864,19 +993,22 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::merge(Tr
// register all surface controls for all callbackIds for this listener that is merging
for (const auto& surfaceControl : currentProcessCallbackInfo.surfaceControls) {
TransactionCompletedListener::getInstance()
- ->addSurfaceControlToCallbacks(surfaceControl,
- currentProcessCallbackInfo.callbackIds);
+ ->addSurfaceControlToCallbacks(currentProcessCallbackInfo, surfaceControl);
}
}
+ for (const auto& cacheId : other.mUncacheBuffers) {
+ mUncacheBuffers.push_back(cacheId);
+ }
+
mInputWindowCommands.merge(other.mInputWindowCommands);
- mContainsBuffer |= other.mContainsBuffer;
+ mMayContainBuffer |= other.mMayContainBuffer;
mEarlyWakeupStart = mEarlyWakeupStart || other.mEarlyWakeupStart;
mEarlyWakeupEnd = mEarlyWakeupEnd || other.mEarlyWakeupEnd;
mApplyToken = other.mApplyToken;
- mFrameTimelineInfo.merge(other.mFrameTimelineInfo);
+ mergeFrameTimelineInfo(mFrameTimelineInfo, other.mFrameTimelineInfo);
other.clear();
return *this;
@@ -887,36 +1019,46 @@ void SurfaceComposerClient::Transaction::clear() {
mDisplayStates.clear();
mListenerCallbacks.clear();
mInputWindowCommands.clear();
- mContainsBuffer = false;
- mForceSynchronous = 0;
+ mUncacheBuffers.clear();
+ mMayContainBuffer = false;
mTransactionNestCount = 0;
mAnimation = false;
mEarlyWakeupStart = false;
mEarlyWakeupEnd = false;
mDesiredPresentTime = 0;
mIsAutoTimestamp = true;
- mFrameTimelineInfo.clear();
+ clearFrameTimelineInfo(mFrameTimelineInfo);
mApplyToken = nullptr;
+ mMergedTransactionIds.clear();
}
uint64_t SurfaceComposerClient::Transaction::getId() {
return mId;
}
+std::vector<uint64_t> SurfaceComposerClient::Transaction::getMergedTransactionIds() {
+ return mMergedTransactionIds;
+}
+
void SurfaceComposerClient::doUncacheBufferTransaction(uint64_t cacheId) {
sp<ISurfaceComposer> sf(ComposerService::getComposerService());
client_cache_t uncacheBuffer;
uncacheBuffer.token = BufferCache::getInstance().getToken();
uncacheBuffer.id = cacheId;
-
- sp<IBinder> applyToken = IInterface::asBinder(TransactionCompletedListener::getIInstance());
- sf->setTransactionState(FrameTimelineInfo{}, {}, {}, 0, applyToken, {}, systemTime(), true,
- uncacheBuffer, false, {}, generateId());
+ Vector<ComposerState> composerStates;
+ status_t status = sf->setTransactionState(FrameTimelineInfo{}, composerStates, {},
+ ISurfaceComposer::eOneWay,
+ Transaction::getDefaultApplyToken(), {}, systemTime(),
+ true, {uncacheBuffer}, false, {}, generateId(), {});
+ if (status != NO_ERROR) {
+ ALOGE_AND_TRACE("SurfaceComposerClient::doUncacheBufferTransaction - %s",
+ strerror(-status));
+ }
}
void SurfaceComposerClient::Transaction::cacheBuffers() {
- if (!mContainsBuffer) {
+ if (!mMayContainBuffer) {
return;
}
@@ -946,7 +1088,11 @@ void SurfaceComposerClient::Transaction::cacheBuffers() {
s->bufferData->buffer = nullptr;
} else {
// Cache-miss. Include the buffer and send the new cacheId.
- cacheId = BufferCache::getInstance().cache(s->bufferData->buffer);
+ std::optional<client_cache_t> uncacheBuffer;
+ cacheId = BufferCache::getInstance().cache(s->bufferData->buffer, uncacheBuffer);
+ if (uncacheBuffer) {
+ mUncacheBuffers.push_back(*uncacheBuffer);
+ }
}
s->bufferData->flags |= BufferData::BufferDataChange::cachedBufferChanged;
s->bufferData->cachedBuffer.token = BufferCache::getInstance().getToken();
@@ -961,12 +1107,58 @@ void SurfaceComposerClient::Transaction::cacheBuffers() {
}
}
+class SyncCallback {
+public:
+ static auto getCallback(std::shared_ptr<SyncCallback>& callbackContext) {
+ return [callbackContext](void* /* unused context */, nsecs_t /* latchTime */,
+ const sp<Fence>& /* presentFence */,
+ const std::vector<SurfaceControlStats>& /* stats */) {
+ if (!callbackContext) {
+ ALOGE("failed to get callback context for SyncCallback");
+ return;
+ }
+ LOG_ALWAYS_FATAL_IF(sem_post(&callbackContext->mSemaphore), "sem_post failed");
+ };
+ }
+ ~SyncCallback() {
+ if (mInitialized) {
+ LOG_ALWAYS_FATAL_IF(sem_destroy(&mSemaphore), "sem_destroy failed");
+ }
+ }
+ void init() {
+ LOG_ALWAYS_FATAL_IF(clock_gettime(CLOCK_MONOTONIC, &mTimeoutTimespec) == -1,
+ "clock_gettime() fail! in SyncCallback::init");
+ mTimeoutTimespec.tv_sec += 4;
+ LOG_ALWAYS_FATAL_IF(sem_init(&mSemaphore, 0, 0), "sem_init failed");
+ mInitialized = true;
+ }
+ void wait() {
+ int result = sem_clockwait(&mSemaphore, CLOCK_MONOTONIC, &mTimeoutTimespec);
+ if (result && errno != ETIMEDOUT && errno != EINTR) {
+ LOG_ALWAYS_FATAL("sem_clockwait failed(%d)", errno);
+ } else if (errno == ETIMEDOUT) {
+ ALOGW("Sync transaction timed out waiting for commit callback.");
+ }
+ }
+ void* getContext() { return static_cast<void*>(this); }
+
+private:
+ sem_t mSemaphore;
+ bool mInitialized = false;
+ timespec mTimeoutTimespec;
+};
+
status_t SurfaceComposerClient::Transaction::apply(bool synchronous, bool oneWay) {
if (mStatus != NO_ERROR) {
return mStatus;
}
- sp<ISurfaceComposer> sf(ComposerService::getComposerService());
+ std::shared_ptr<SyncCallback> syncCallback = std::make_shared<SyncCallback>();
+ if (synchronous) {
+ syncCallback->init();
+ addTransactionCommittedCallback(SyncCallback::getCallback(syncCallback),
+ /*callbackContext=*/nullptr);
+ }
bool hasListenerCallbacks = !mListenerCallbacks.empty();
std::vector<ListenerCallbacks> listenerCallbacks;
@@ -1001,27 +1193,22 @@ status_t SurfaceComposerClient::Transaction::apply(bool synchronous, bool oneWay
Vector<DisplayState> displayStates;
uint32_t flags = 0;
- mForceSynchronous |= synchronous;
-
- for (auto const& kv : mComposerStates){
+ for (auto const& kv : mComposerStates) {
composerStates.add(kv.second);
}
displayStates = std::move(mDisplayStates);
- if (mForceSynchronous) {
- flags |= ISurfaceComposer::eSynchronous;
- }
if (mAnimation) {
flags |= ISurfaceComposer::eAnimation;
}
if (oneWay) {
- if (mForceSynchronous) {
- ALOGE("Transaction attempted to set synchronous and one way at the same time"
- " this is an invalid request. Synchronous will win for safety");
- } else {
- flags |= ISurfaceComposer::eOneWay;
- }
+ if (synchronous) {
+ ALOGE("Transaction attempted to set synchronous and one way at the same time"
+ " this is an invalid request. Synchronous will win for safety");
+ } else {
+ flags |= ISurfaceComposer::eOneWay;
+ }
}
// If both mEarlyWakeupStart and mEarlyWakeupEnd are set
@@ -1033,31 +1220,58 @@ status_t SurfaceComposerClient::Transaction::apply(bool synchronous, bool oneWay
flags |= ISurfaceComposer::eEarlyWakeupEnd;
}
- sp<IBinder> applyToken = mApplyToken
- ? mApplyToken
- : IInterface::asBinder(TransactionCompletedListener::getIInstance());
+ sp<IBinder> applyToken = mApplyToken ? mApplyToken : sApplyToken;
+ sp<ISurfaceComposer> sf(ComposerService::getComposerService());
sf->setTransactionState(mFrameTimelineInfo, composerStates, displayStates, flags, applyToken,
mInputWindowCommands, mDesiredPresentTime, mIsAutoTimestamp,
- {} /*uncacheBuffer - only set in doUncacheBufferTransaction*/,
- hasListenerCallbacks, listenerCallbacks, mId);
+ mUncacheBuffers, hasListenerCallbacks, listenerCallbacks, mId,
+ mMergedTransactionIds);
mId = generateId();
// Clear the current states and flags
clear();
+ if (synchronous) {
+ syncCallback->wait();
+ }
+
mStatus = NO_ERROR;
return NO_ERROR;
}
+sp<IBinder> SurfaceComposerClient::Transaction::sApplyToken = new BBinder();
+
+sp<IBinder> SurfaceComposerClient::Transaction::getDefaultApplyToken() {
+ return sApplyToken;
+}
+
+void SurfaceComposerClient::Transaction::setDefaultApplyToken(sp<IBinder> applyToken) {
+ sApplyToken = applyToken;
+}
+
+status_t SurfaceComposerClient::Transaction::sendSurfaceFlushJankDataTransaction(
+ const sp<SurfaceControl>& sc) {
+ Transaction t;
+ layer_state_t* s = t.getLayerState(sc);
+ if (!s) {
+ return BAD_INDEX;
+ }
+
+ s->what |= layer_state_t::eFlushJankData;
+ t.registerSurfaceControlForCallback(sc);
+ return t.apply(/*sync=*/false, /* oneWay=*/true);
+}
// ---------------------------------------------------------------------------
-sp<IBinder> SurfaceComposerClient::createDisplay(const String8& displayName, bool secure) {
+sp<IBinder> SurfaceComposerClient::createDisplay(const String8& displayName, bool secure,
+ float requestedRefereshRate) {
sp<IBinder> display = nullptr;
binder::Status status =
ComposerServiceAIDL::getComposerService()->createDisplay(std::string(
displayName.c_str()),
- secure, &display);
+ secure, requestedRefereshRate,
+ &display);
return status.isOk() ? display : nullptr;
}
@@ -1080,21 +1294,6 @@ std::vector<PhysicalDisplayId> SurfaceComposerClient::getPhysicalDisplayIds() {
return physicalDisplayIds;
}
-status_t SurfaceComposerClient::getPrimaryPhysicalDisplayId(PhysicalDisplayId* id) {
- int64_t displayId;
- binder::Status status =
- ComposerServiceAIDL::getComposerService()->getPrimaryPhysicalDisplayId(&displayId);
- if (status.isOk()) {
- *id = *DisplayId::fromValue<PhysicalDisplayId>(static_cast<uint64_t>(displayId));
- }
- return status.transactionError();
-}
-
-std::optional<PhysicalDisplayId> SurfaceComposerClient::getInternalDisplayId() {
- ComposerServiceAIDL& instance = ComposerServiceAIDL::getInstance();
- return instance.getInternalDisplayId();
-}
-
sp<IBinder> SurfaceComposerClient::getPhysicalDisplayToken(PhysicalDisplayId displayId) {
sp<IBinder> display = nullptr;
binder::Status status =
@@ -1103,11 +1302,6 @@ sp<IBinder> SurfaceComposerClient::getPhysicalDisplayToken(PhysicalDisplayId dis
return status.isOk() ? display : nullptr;
}
-sp<IBinder> SurfaceComposerClient::getInternalDisplayToken() {
- ComposerServiceAIDL& instance = ComposerServiceAIDL::getInstance();
- return instance.getInternalDisplayToken();
-}
-
void SurfaceComposerClient::Transaction::setAnimationTransaction() {
mAnimation = true;
}
@@ -1141,8 +1335,7 @@ void SurfaceComposerClient::Transaction::registerSurfaceControlForCallback(
auto& callbackInfo = mListenerCallbacks[TransactionCompletedListener::getIInstance()];
callbackInfo.surfaceControls.insert(sc);
- TransactionCompletedListener::getInstance()
- ->addSurfaceControlToCallbacks(sc, callbackInfo.callbackIds);
+ TransactionCompletedListener::getInstance()->addSurfaceControlToCallbacks(callbackInfo, sc);
}
SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setPosition(
@@ -1170,21 +1363,6 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::hide(
return setFlags(sc, layer_state_t::eLayerHidden, layer_state_t::eLayerHidden);
}
-SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setSize(
- const sp<SurfaceControl>& sc, uint32_t w, uint32_t h) {
- layer_state_t* s = getLayerState(sc);
- if (!s) {
- mStatus = BAD_INDEX;
- return *this;
- }
- s->what |= layer_state_t::eSizeChanged;
- s->w = w;
- s->h = h;
-
- registerSurfaceControlForCallback(sc);
- return *this;
-}
-
SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setLayer(
const sp<SurfaceControl>& sc, int32_t z) {
layer_state_t* s = getLayerState(sc);
@@ -1227,7 +1405,9 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setFlags
if ((mask & layer_state_t::eLayerOpaque) || (mask & layer_state_t::eLayerHidden) ||
(mask & layer_state_t::eLayerSecure) || (mask & layer_state_t::eLayerSkipScreenshot) ||
(mask & layer_state_t::eEnableBackpressure) ||
- (mask & layer_state_t::eLayerIsDisplayDecoration)) {
+ (mask & layer_state_t::eIgnoreDestinationFrame) ||
+ (mask & layer_state_t::eLayerIsDisplayDecoration) ||
+ (mask & layer_state_t::eLayerIsRefreshRateIndicator)) {
s->what |= layer_state_t::eFlagsChanged;
}
s->flags &= ~mask;
@@ -1278,7 +1458,7 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setAlpha
ALOGE("SurfaceComposerClient::Transaction::setAlpha: invalid alpha %f, clamping", alpha);
}
s->what |= layer_state_t::eAlphaChanged;
- s->alpha = std::clamp(alpha, 0.f, 1.f);
+ s->color.a = std::clamp(alpha, 0.f, 1.f);
registerSurfaceControlForCallback(sc);
return *this;
@@ -1409,7 +1589,7 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setColor
return *this;
}
s->what |= layer_state_t::eColorChanged;
- s->color = color;
+ s->color.rgb = color;
registerSurfaceControlForCallback(sc);
return *this;
@@ -1424,8 +1604,8 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setBackg
}
s->what |= layer_state_t::eBackgroundColorChanged;
- s->color = color;
- s->bgColorAlpha = alpha;
+ s->bgColor.rgb = color;
+ s->bgColor.a = alpha;
s->bgColorDataspace = dataspace;
registerSurfaceControlForCallback(sc);
@@ -1439,8 +1619,8 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setTrans
mStatus = BAD_INDEX;
return *this;
}
- s->what |= layer_state_t::eTransformChanged;
- s->transform = transform;
+ s->what |= layer_state_t::eBufferTransformChanged;
+ s->bufferTransform = transform;
registerSurfaceControlForCallback(sc);
return *this;
@@ -1478,7 +1658,6 @@ std::shared_ptr<BufferData> SurfaceComposerClient::Transaction::getAndClearBuffe
s->what &= ~layer_state_t::eBufferChanged;
s->bufferData = nullptr;
- mContainsBuffer = false;
return bufferData;
}
@@ -1497,7 +1676,7 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setBuffe
SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setBuffer(
const sp<SurfaceControl>& sc, const sp<GraphicBuffer>& buffer,
const std::optional<sp<Fence>>& fence, const std::optional<uint64_t>& optFrameNumber,
- ReleaseBufferCallback callback) {
+ uint32_t producerId, ReleaseBufferCallback callback) {
layer_state_t* s = getLayerState(sc);
if (!s) {
mStatus = BAD_INDEX;
@@ -1506,28 +1685,25 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setBuffe
releaseBufferIfOverwriting(*s);
- if (buffer == nullptr) {
- s->what &= ~layer_state_t::eBufferChanged;
- s->bufferData = nullptr;
- mContainsBuffer = false;
- return *this;
- }
-
std::shared_ptr<BufferData> bufferData = std::make_shared<BufferData>();
bufferData->buffer = buffer;
- uint64_t frameNumber = sc->resolveFrameNumber(optFrameNumber);
- bufferData->frameNumber = frameNumber;
- bufferData->flags |= BufferData::BufferDataChange::frameNumberChanged;
- if (fence) {
- bufferData->acquireFence = *fence;
- bufferData->flags |= BufferData::BufferDataChange::fenceChanged;
- }
- bufferData->releaseBufferEndpoint =
- IInterface::asBinder(TransactionCompletedListener::getIInstance());
+ if (buffer) {
+ uint64_t frameNumber = sc->resolveFrameNumber(optFrameNumber);
+ bufferData->frameNumber = frameNumber;
+ bufferData->producerId = producerId;
+ bufferData->flags |= BufferData::BufferDataChange::frameNumberChanged;
+ if (fence) {
+ bufferData->acquireFence = *fence;
+ bufferData->flags |= BufferData::BufferDataChange::fenceChanged;
+ }
+ bufferData->releaseBufferEndpoint =
+ IInterface::asBinder(TransactionCompletedListener::getIInstance());
+ setReleaseBufferCallback(bufferData.get(), callback);
+ }
+
if (mIsAutoTimestamp) {
mDesiredPresentTime = systemTime();
}
- setReleaseBufferCallback(bufferData.get(), callback);
s->what |= layer_state_t::eBufferChanged;
s->bufferData = std::move(bufferData);
registerSurfaceControlForCallback(sc);
@@ -1544,7 +1720,26 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setBuffe
const std::vector<SurfaceControlStats>&) {},
nullptr);
- mContainsBuffer = true;
+ mMayContainBuffer = true;
+ return *this;
+}
+
+SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::unsetBuffer(
+ const sp<SurfaceControl>& sc) {
+ layer_state_t* s = getLayerState(sc);
+ if (!s) {
+ mStatus = BAD_INDEX;
+ return *this;
+ }
+
+ if (!(s->what & layer_state_t::eBufferChanged)) {
+ return *this;
+ }
+
+ releaseBufferIfOverwriting(*s);
+
+ s->what &= ~layer_state_t::eBufferChanged;
+ s->bufferData = nullptr;
return *this;
}
@@ -1579,6 +1774,35 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setDatas
return *this;
}
+SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setExtendedRangeBrightness(
+ const sp<SurfaceControl>& sc, float currentBufferRatio, float desiredRatio) {
+ layer_state_t* s = getLayerState(sc);
+ if (!s) {
+ mStatus = BAD_INDEX;
+ return *this;
+ }
+ s->what |= layer_state_t::eExtendedRangeBrightnessChanged;
+ s->currentHdrSdrRatio = currentBufferRatio;
+ s->desiredHdrSdrRatio = desiredRatio;
+
+ registerSurfaceControlForCallback(sc);
+ return *this;
+}
+
+SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setCachingHint(
+ const sp<SurfaceControl>& sc, gui::CachingHint cachingHint) {
+ layer_state_t* s = getLayerState(sc);
+ if (!s) {
+ mStatus = BAD_INDEX;
+ return *this;
+ }
+ s->what |= layer_state_t::eCachingHintChanged;
+ s->cachingHint = cachingHint;
+
+ registerSurfaceControlForCallback(sc);
+ return *this;
+}
+
SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setHdrMetadata(
const sp<SurfaceControl>& sc, const HdrMetadata& hdrMetadata) {
layer_state_t* s = getLayerState(sc);
@@ -1732,8 +1956,10 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setFocus
return *this;
}
-SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::syncInputWindows() {
- mInputWindowCommands.syncInputWindows = true;
+SurfaceComposerClient::Transaction&
+SurfaceComposerClient::Transaction::addWindowInfosReportedListener(
+ sp<gui::IWindowInfosReportedListener> windowInfosReportedListener) {
+ mInputWindowCommands.windowInfosReportedListeners.insert(windowInfosReportedListener);
return *this;
}
@@ -1840,6 +2066,19 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setFrame
return *this;
}
+SurfaceComposerClient::Transaction&
+SurfaceComposerClient::Transaction::setDefaultFrameRateCompatibility(const sp<SurfaceControl>& sc,
+ int8_t compatibility) {
+ layer_state_t* s = getLayerState(sc);
+ if (!s) {
+ mStatus = BAD_INDEX;
+ return *this;
+ }
+ s->what |= layer_state_t::eDefaultFrameRateCompatibilityChanged;
+ s->defaultFrameRateCompatibility = compatibility;
+ return *this;
+}
+
SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setFixedTransformHint(
const sp<SurfaceControl>& sc, int32_t fixedTransformHint) {
layer_state_t* s = getLayerState(sc);
@@ -1858,7 +2097,7 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setFixed
SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setFrameTimelineInfo(
const FrameTimelineInfo& frameTimelineInfo) {
- mFrameTimelineInfo.merge(frameTimelineInfo);
+ mergeFrameTimelineInfo(mFrameTimelineInfo, frameTimelineInfo);
return *this;
}
@@ -1952,6 +2191,23 @@ SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setDropI
return *this;
}
+SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::enableBorder(
+ const sp<SurfaceControl>& sc, bool shouldEnable, float width, const half4& color) {
+ layer_state_t* s = getLayerState(sc);
+ if (!s) {
+ mStatus = BAD_INDEX;
+ return *this;
+ }
+
+ s->what |= layer_state_t::eRenderBorderChanged;
+ s->borderEnabled = shouldEnable;
+ s->borderWidth = width;
+ s->borderColor = color;
+
+ registerSurfaceControlForCallback(sc);
+ return *this;
+}
+
// ---------------------------------------------------------------------------
DisplayState& SurfaceComposerClient::Transaction::getDisplayState(const sp<IBinder>& token) {
@@ -2007,7 +2263,6 @@ void SurfaceComposerClient::Transaction::setDisplayProjection(const sp<IBinder>&
s.layerStackSpaceRect = layerStackRect;
s.orientedDisplaySpaceRect = displayRect;
s.what |= DisplayState::eDisplayProjectionChanged;
- mForceSynchronous = true; // TODO: do we actually still need this?
}
void SurfaceComposerClient::Transaction::setDisplaySize(const sp<IBinder>& token, uint32_t width, uint32_t height) {
@@ -2017,6 +2272,73 @@ void SurfaceComposerClient::Transaction::setDisplaySize(const sp<IBinder>& token
s.what |= DisplayState::eDisplaySizeChanged;
}
+// copied from FrameTimelineInfo::merge()
+void SurfaceComposerClient::Transaction::mergeFrameTimelineInfo(FrameTimelineInfo& t,
+ const FrameTimelineInfo& other) {
+ // When merging vsync Ids we take the oldest valid one
+ if (t.vsyncId != FrameTimelineInfo::INVALID_VSYNC_ID &&
+ other.vsyncId != FrameTimelineInfo::INVALID_VSYNC_ID) {
+ if (other.vsyncId > t.vsyncId) {
+ t.vsyncId = other.vsyncId;
+ t.inputEventId = other.inputEventId;
+ t.startTimeNanos = other.startTimeNanos;
+ t.useForRefreshRateSelection = other.useForRefreshRateSelection;
+ }
+ } else if (t.vsyncId == FrameTimelineInfo::INVALID_VSYNC_ID) {
+ t.vsyncId = other.vsyncId;
+ t.inputEventId = other.inputEventId;
+ t.startTimeNanos = other.startTimeNanos;
+ t.useForRefreshRateSelection = other.useForRefreshRateSelection;
+ }
+}
+
+// copied from FrameTimelineInfo::clear()
+void SurfaceComposerClient::Transaction::clearFrameTimelineInfo(FrameTimelineInfo& t) {
+ t.vsyncId = FrameTimelineInfo::INVALID_VSYNC_ID;
+ t.inputEventId = os::IInputConstants::INVALID_INPUT_EVENT_ID;
+ t.startTimeNanos = 0;
+ t.useForRefreshRateSelection = false;
+}
+
+SurfaceComposerClient::Transaction&
+SurfaceComposerClient::Transaction::setTrustedPresentationCallback(
+ const sp<SurfaceControl>& sc, TrustedPresentationCallback cb,
+ const TrustedPresentationThresholds& thresholds, void* context,
+ sp<SurfaceComposerClient::PresentationCallbackRAII>& outCallbackRef) {
+ auto listener = TransactionCompletedListener::getInstance();
+ outCallbackRef = listener->addTrustedPresentationCallback(cb, sc->getLayerId(), context);
+
+ layer_state_t* s = getLayerState(sc);
+ if (!s) {
+ mStatus = BAD_INDEX;
+ return *this;
+ }
+ s->what |= layer_state_t::eTrustedPresentationInfoChanged;
+ s->trustedPresentationThresholds = thresholds;
+ s->trustedPresentationListener.callbackInterface = TransactionCompletedListener::getIInstance();
+ s->trustedPresentationListener.callbackId = sc->getLayerId();
+
+ return *this;
+}
+
+SurfaceComposerClient::Transaction&
+SurfaceComposerClient::Transaction::clearTrustedPresentationCallback(const sp<SurfaceControl>& sc) {
+ auto listener = TransactionCompletedListener::getInstance();
+ listener->clearTrustedPresentationCallback(sc->getLayerId());
+
+ layer_state_t* s = getLayerState(sc);
+ if (!s) {
+ mStatus = BAD_INDEX;
+ return *this;
+ }
+ s->what |= layer_state_t::eTrustedPresentationInfoChanged;
+ s->trustedPresentationThresholds = TrustedPresentationThresholds();
+ s->trustedPresentationListener.callbackInterface = nullptr;
+ s->trustedPresentationListener.callbackId = -1;
+
+ return *this;
+}
+
// ---------------------------------------------------------------------------
SurfaceComposerClient::SurfaceComposerClient() : mStatus(NO_INIT) {}
@@ -2025,11 +2347,11 @@ SurfaceComposerClient::SurfaceComposerClient(const sp<ISurfaceComposerClient>& c
: mStatus(NO_ERROR), mClient(client) {}
void SurfaceComposerClient::onFirstRef() {
- sp<ISurfaceComposer> sf(ComposerService::getComposerService());
+ sp<gui::ISurfaceComposer> sf(ComposerServiceAIDL::getComposerService());
if (sf != nullptr && mStatus == NO_INIT) {
sp<ISurfaceComposerClient> conn;
- conn = sf->createConnection();
- if (conn != nullptr) {
+ binder::Status status = sf->createConnection(&conn);
+ if (status.isOk() && conn != nullptr) {
mClient = conn;
mStatus = NO_ERROR;
}
@@ -2066,8 +2388,14 @@ void SurfaceComposerClient::dispose() {
mStatus = NO_INIT;
}
+status_t SurfaceComposerClient::bootFinished() {
+ sp<gui::ISurfaceComposer> sf(ComposerServiceAIDL::getComposerService());
+ binder::Status status = sf->bootFinished();
+ return statusTFromBinderStatus(status);
+}
+
sp<SurfaceControl> SurfaceComposerClient::createSurface(const String8& name, uint32_t w, uint32_t h,
- PixelFormat format, uint32_t flags,
+ PixelFormat format, int32_t flags,
const sp<IBinder>& parentHandle,
LayerMetadata metadata,
uint32_t* outTransformHint) {
@@ -2077,38 +2405,13 @@ sp<SurfaceControl> SurfaceComposerClient::createSurface(const String8& name, uin
return s;
}
-sp<SurfaceControl> SurfaceComposerClient::createWithSurfaceParent(const String8& name, uint32_t w,
- uint32_t h, PixelFormat format,
- uint32_t flags, Surface* parent,
- LayerMetadata metadata,
- uint32_t* outTransformHint) {
- sp<SurfaceControl> sur;
- status_t err = mStatus;
-
- if (mStatus == NO_ERROR) {
- sp<IBinder> handle;
- sp<IGraphicBufferProducer> parentGbp = parent->getIGraphicBufferProducer();
- sp<IGraphicBufferProducer> gbp;
-
- uint32_t transformHint = 0;
- int32_t id = -1;
- err = mClient->createWithSurfaceParent(name, w, h, format, flags, parentGbp,
- std::move(metadata), &handle, &gbp, &id,
- &transformHint);
- if (outTransformHint) {
- *outTransformHint = transformHint;
- }
- ALOGE_IF(err, "SurfaceComposerClient::createWithSurfaceParent error %s", strerror(-err));
- if (err == NO_ERROR) {
- return new SurfaceControl(this, handle, gbp, id, transformHint);
- }
- }
- return nullptr;
+static std::string toString(const String16& string) {
+ return std::string(String8(string).c_str());
}
status_t SurfaceComposerClient::createSurfaceChecked(const String8& name, uint32_t w, uint32_t h,
PixelFormat format,
- sp<SurfaceControl>* outSurface, uint32_t flags,
+ sp<SurfaceControl>* outSurface, int32_t flags,
const sp<IBinder>& parentHandle,
LayerMetadata metadata,
uint32_t* outTransformHint) {
@@ -2116,21 +2419,18 @@ status_t SurfaceComposerClient::createSurfaceChecked(const String8& name, uint32
status_t err = mStatus;
if (mStatus == NO_ERROR) {
- sp<IBinder> handle;
- sp<IGraphicBufferProducer> gbp;
-
- uint32_t transformHint = 0;
- int32_t id = -1;
- err = mClient->createSurface(name, w, h, format, flags, parentHandle, std::move(metadata),
- &handle, &gbp, &id, &transformHint);
-
+ gui::CreateSurfaceResult result;
+ binder::Status status = mClient->createSurface(std::string(name.c_str()), flags,
+ parentHandle, std::move(metadata), &result);
+ err = statusTFromBinderStatus(status);
if (outTransformHint) {
- *outTransformHint = transformHint;
+ *outTransformHint = result.transformHint;
}
ALOGE_IF(err, "SurfaceComposerClient::createSurface error %s", strerror(-err));
if (err == NO_ERROR) {
- *outSurface =
- new SurfaceControl(this, handle, gbp, id, w, h, format, transformHint, flags);
+ *outSurface = new SurfaceControl(this, result.handle, result.layerId,
+ toString(result.layerName), w, h, format,
+ result.transformHint, flags);
}
}
return err;
@@ -2141,12 +2441,22 @@ sp<SurfaceControl> SurfaceComposerClient::mirrorSurface(SurfaceControl* mirrorFr
return nullptr;
}
- sp<IBinder> handle;
sp<IBinder> mirrorFromHandle = mirrorFromSurface->getHandle();
- int32_t layer_id = -1;
- status_t err = mClient->mirrorSurface(mirrorFromHandle, &handle, &layer_id);
+ gui::CreateSurfaceResult result;
+ const binder::Status status = mClient->mirrorSurface(mirrorFromHandle, &result);
+ const status_t err = statusTFromBinderStatus(status);
if (err == NO_ERROR) {
- return new SurfaceControl(this, handle, nullptr, layer_id, true /* owned */);
+ return new SurfaceControl(this, result.handle, result.layerId, toString(result.layerName));
+ }
+ return nullptr;
+}
+
+sp<SurfaceControl> SurfaceComposerClient::mirrorDisplay(DisplayId displayId) {
+ gui::CreateSurfaceResult result;
+ const binder::Status status = mClient->mirrorDisplay(displayId.value, &result);
+ const status_t err = statusTFromBinderStatus(status);
+ if (err == NO_ERROR) {
+ return new SurfaceControl(this, result.handle, result.layerId, toString(result.layerName));
}
return nullptr;
}
@@ -2155,7 +2465,8 @@ status_t SurfaceComposerClient::clearLayerFrameStats(const sp<IBinder>& token) c
if (mStatus != NO_ERROR) {
return mStatus;
}
- return mClient->clearLayerFrameStats(token);
+ const binder::Status status = mClient->clearLayerFrameStats(token);
+ return statusTFromBinderStatus(status);
}
status_t SurfaceComposerClient::getLayerFrameStats(const sp<IBinder>& token,
@@ -2163,21 +2474,28 @@ status_t SurfaceComposerClient::getLayerFrameStats(const sp<IBinder>& token,
if (mStatus != NO_ERROR) {
return mStatus;
}
- return mClient->getLayerFrameStats(token, outStats);
+ gui::FrameStats stats;
+ const binder::Status status = mClient->getLayerFrameStats(token, &stats);
+ if (status.isOk()) {
+ outStats->refreshPeriodNano = stats.refreshPeriodNano;
+ outStats->desiredPresentTimesNano.setCapacity(stats.desiredPresentTimesNano.size());
+ for (const auto& t : stats.desiredPresentTimesNano) {
+ outStats->desiredPresentTimesNano.add(t);
+ }
+ outStats->actualPresentTimesNano.setCapacity(stats.actualPresentTimesNano.size());
+ for (const auto& t : stats.actualPresentTimesNano) {
+ outStats->actualPresentTimesNano.add(t);
+ }
+ outStats->frameReadyTimesNano.setCapacity(stats.frameReadyTimesNano.size());
+ for (const auto& t : stats.frameReadyTimesNano) {
+ outStats->frameReadyTimesNano.add(t);
+ }
+ }
+ return statusTFromBinderStatus(status);
}
// ----------------------------------------------------------------------------
-status_t SurfaceComposerClient::enableVSyncInjections(bool enable) {
- sp<ISurfaceComposer> sf(ComposerService::getComposerService());
- return sf->enableVSyncInjections(enable);
-}
-
-status_t SurfaceComposerClient::injectVSync(nsecs_t when) {
- sp<ISurfaceComposer> sf(ComposerService::getComposerService());
- return sf->injectVSync(when);
-}
-
status_t SurfaceComposerClient::getDisplayState(const sp<IBinder>& display,
ui::DisplayState* state) {
gui::DisplayState ds;
@@ -2189,23 +2507,135 @@ status_t SurfaceComposerClient::getDisplayState(const sp<IBinder>& display,
state->layerStackSpaceRect =
ui::Size(ds.layerStackSpaceRect.width, ds.layerStackSpaceRect.height);
}
- return status.transactionError();
+ return statusTFromBinderStatus(status);
+}
+
+status_t SurfaceComposerClient::getStaticDisplayInfo(int64_t displayId,
+ ui::StaticDisplayInfo* outInfo) {
+ using Tag = android::gui::DeviceProductInfo::ManufactureOrModelDate::Tag;
+ gui::StaticDisplayInfo ginfo;
+ binder::Status status =
+ ComposerServiceAIDL::getComposerService()->getStaticDisplayInfo(displayId, &ginfo);
+ if (status.isOk()) {
+ // convert gui::StaticDisplayInfo to ui::StaticDisplayInfo
+ outInfo->connectionType = static_cast<ui::DisplayConnectionType>(ginfo.connectionType);
+ outInfo->density = ginfo.density;
+ outInfo->secure = ginfo.secure;
+ outInfo->installOrientation = static_cast<ui::Rotation>(ginfo.installOrientation);
+
+ DeviceProductInfo info;
+ std::optional<gui::DeviceProductInfo> dpi = ginfo.deviceProductInfo;
+ gui::DeviceProductInfo::ManufactureOrModelDate& date = dpi->manufactureOrModelDate;
+ info.name = dpi->name;
+ if (dpi->manufacturerPnpId.size() > 0) {
+ // copid from PnpId = std::array<char, 4> in ui/DeviceProductInfo.h
+ constexpr int kMaxPnpIdSize = 4;
+ size_t count = std::max<size_t>(kMaxPnpIdSize, dpi->manufacturerPnpId.size());
+ std::copy_n(dpi->manufacturerPnpId.begin(), count, info.manufacturerPnpId.begin());
+ }
+ if (dpi->relativeAddress.size() > 0) {
+ std::copy(dpi->relativeAddress.begin(), dpi->relativeAddress.end(),
+ std::back_inserter(info.relativeAddress));
+ }
+ info.productId = dpi->productId;
+ if (date.getTag() == Tag::modelYear) {
+ DeviceProductInfo::ModelYear modelYear;
+ modelYear.year = static_cast<uint32_t>(date.get<Tag::modelYear>().year);
+ info.manufactureOrModelDate = modelYear;
+ } else if (date.getTag() == Tag::manufactureYear) {
+ DeviceProductInfo::ManufactureYear manufactureYear;
+ manufactureYear.year = date.get<Tag::manufactureYear>().modelYear.year;
+ info.manufactureOrModelDate = manufactureYear;
+ } else if (date.getTag() == Tag::manufactureWeekAndYear) {
+ DeviceProductInfo::ManufactureWeekAndYear weekAndYear;
+ weekAndYear.year =
+ date.get<Tag::manufactureWeekAndYear>().manufactureYear.modelYear.year;
+ weekAndYear.week = date.get<Tag::manufactureWeekAndYear>().week;
+ info.manufactureOrModelDate = weekAndYear;
+ }
+
+ outInfo->deviceProductInfo = info;
+ }
+ return statusTFromBinderStatus(status);
}
-status_t SurfaceComposerClient::getStaticDisplayInfo(const sp<IBinder>& display,
- ui::StaticDisplayInfo* info) {
- return ComposerService::getComposerService()->getStaticDisplayInfo(display, info);
+void SurfaceComposerClient::getDynamicDisplayInfoInternal(gui::DynamicDisplayInfo& ginfo,
+ ui::DynamicDisplayInfo*& outInfo) {
+ // convert gui::DynamicDisplayInfo to ui::DynamicDisplayInfo
+ outInfo->supportedDisplayModes.clear();
+ outInfo->supportedDisplayModes.reserve(ginfo.supportedDisplayModes.size());
+ for (const auto& mode : ginfo.supportedDisplayModes) {
+ ui::DisplayMode outMode;
+ outMode.id = mode.id;
+ outMode.resolution.width = mode.resolution.width;
+ outMode.resolution.height = mode.resolution.height;
+ outMode.xDpi = mode.xDpi;
+ outMode.yDpi = mode.yDpi;
+ outMode.refreshRate = mode.refreshRate;
+ outMode.appVsyncOffset = mode.appVsyncOffset;
+ outMode.sfVsyncOffset = mode.sfVsyncOffset;
+ outMode.presentationDeadline = mode.presentationDeadline;
+ outMode.group = mode.group;
+ std::transform(mode.supportedHdrTypes.begin(), mode.supportedHdrTypes.end(),
+ std::back_inserter(outMode.supportedHdrTypes),
+ [](const int32_t& value) { return static_cast<ui::Hdr>(value); });
+ outInfo->supportedDisplayModes.push_back(outMode);
+ }
+
+ outInfo->activeDisplayModeId = ginfo.activeDisplayModeId;
+ outInfo->renderFrameRate = ginfo.renderFrameRate;
+
+ outInfo->supportedColorModes.clear();
+ outInfo->supportedColorModes.reserve(ginfo.supportedColorModes.size());
+ for (const auto& cmode : ginfo.supportedColorModes) {
+ outInfo->supportedColorModes.push_back(static_cast<ui::ColorMode>(cmode));
+ }
+
+ outInfo->activeColorMode = static_cast<ui::ColorMode>(ginfo.activeColorMode);
+
+ std::vector<ui::Hdr> types;
+ types.reserve(ginfo.hdrCapabilities.supportedHdrTypes.size());
+ for (const auto& hdr : ginfo.hdrCapabilities.supportedHdrTypes) {
+ types.push_back(static_cast<ui::Hdr>(hdr));
+ }
+ outInfo->hdrCapabilities = HdrCapabilities(types, ginfo.hdrCapabilities.maxLuminance,
+ ginfo.hdrCapabilities.maxAverageLuminance,
+ ginfo.hdrCapabilities.minLuminance);
+
+ outInfo->autoLowLatencyModeSupported = ginfo.autoLowLatencyModeSupported;
+ outInfo->gameContentTypeSupported = ginfo.gameContentTypeSupported;
+ outInfo->preferredBootDisplayMode = ginfo.preferredBootDisplayMode;
+}
+
+status_t SurfaceComposerClient::getDynamicDisplayInfoFromId(int64_t displayId,
+ ui::DynamicDisplayInfo* outInfo) {
+ gui::DynamicDisplayInfo ginfo;
+ binder::Status status =
+ ComposerServiceAIDL::getComposerService()->getDynamicDisplayInfoFromId(displayId,
+ &ginfo);
+ if (status.isOk()) {
+ getDynamicDisplayInfoInternal(ginfo, outInfo);
+ }
+ return statusTFromBinderStatus(status);
}
-status_t SurfaceComposerClient::getDynamicDisplayInfo(const sp<IBinder>& display,
- ui::DynamicDisplayInfo* info) {
- return ComposerService::getComposerService()->getDynamicDisplayInfo(display, info);
+status_t SurfaceComposerClient::getDynamicDisplayInfoFromToken(const sp<IBinder>& display,
+ ui::DynamicDisplayInfo* outInfo) {
+ gui::DynamicDisplayInfo ginfo;
+ binder::Status status =
+ ComposerServiceAIDL::getComposerService()->getDynamicDisplayInfoFromToken(display,
+ &ginfo);
+ if (status.isOk()) {
+ getDynamicDisplayInfoInternal(ginfo, outInfo);
+ }
+ return statusTFromBinderStatus(status);
}
status_t SurfaceComposerClient::getActiveDisplayMode(const sp<IBinder>& display,
ui::DisplayMode* mode) {
ui::DynamicDisplayInfo info;
- status_t result = getDynamicDisplayInfo(display, &info);
+
+ status_t result = getDynamicDisplayInfoFromToken(display, &info);
if (result != NO_ERROR) {
return result;
}
@@ -2219,58 +2649,109 @@ status_t SurfaceComposerClient::getActiveDisplayMode(const sp<IBinder>& display,
return NAME_NOT_FOUND;
}
-status_t SurfaceComposerClient::setDesiredDisplayModeSpecs(
- const sp<IBinder>& displayToken, ui::DisplayModeId defaultMode, bool allowGroupSwitching,
- float primaryRefreshRateMin, float primaryRefreshRateMax, float appRequestRefreshRateMin,
- float appRequestRefreshRateMax) {
- return ComposerService::getComposerService()
- ->setDesiredDisplayModeSpecs(displayToken, defaultMode, allowGroupSwitching,
- primaryRefreshRateMin, primaryRefreshRateMax,
- appRequestRefreshRateMin, appRequestRefreshRateMax);
+status_t SurfaceComposerClient::setDesiredDisplayModeSpecs(const sp<IBinder>& displayToken,
+ const gui::DisplayModeSpecs& specs) {
+ binder::Status status =
+ ComposerServiceAIDL::getComposerService()->setDesiredDisplayModeSpecs(displayToken,
+ specs);
+ return statusTFromBinderStatus(status);
}
status_t SurfaceComposerClient::getDesiredDisplayModeSpecs(const sp<IBinder>& displayToken,
- ui::DisplayModeId* outDefaultMode,
- bool* outAllowGroupSwitching,
- float* outPrimaryRefreshRateMin,
- float* outPrimaryRefreshRateMax,
- float* outAppRequestRefreshRateMin,
- float* outAppRequestRefreshRateMax) {
- return ComposerService::getComposerService()
- ->getDesiredDisplayModeSpecs(displayToken, outDefaultMode, outAllowGroupSwitching,
- outPrimaryRefreshRateMin, outPrimaryRefreshRateMax,
- outAppRequestRefreshRateMin, outAppRequestRefreshRateMax);
+ gui::DisplayModeSpecs* outSpecs) {
+ if (!outSpecs) {
+ return BAD_VALUE;
+ }
+ binder::Status status =
+ ComposerServiceAIDL::getComposerService()->getDesiredDisplayModeSpecs(displayToken,
+ outSpecs);
+ return statusTFromBinderStatus(status);
}
status_t SurfaceComposerClient::getDisplayNativePrimaries(const sp<IBinder>& display,
ui::DisplayPrimaries& outPrimaries) {
- return ComposerService::getComposerService()->getDisplayNativePrimaries(display, outPrimaries);
+ gui::DisplayPrimaries primaries;
+ binder::Status status =
+ ComposerServiceAIDL::getComposerService()->getDisplayNativePrimaries(display,
+ &primaries);
+ if (status.isOk()) {
+ outPrimaries.red.X = primaries.red.X;
+ outPrimaries.red.Y = primaries.red.Y;
+ outPrimaries.red.Z = primaries.red.Z;
+
+ outPrimaries.green.X = primaries.green.X;
+ outPrimaries.green.Y = primaries.green.Y;
+ outPrimaries.green.Z = primaries.green.Z;
+
+ outPrimaries.blue.X = primaries.blue.X;
+ outPrimaries.blue.Y = primaries.blue.Y;
+ outPrimaries.blue.Z = primaries.blue.Z;
+
+ outPrimaries.white.X = primaries.white.X;
+ outPrimaries.white.Y = primaries.white.Y;
+ outPrimaries.white.Z = primaries.white.Z;
+ }
+ return statusTFromBinderStatus(status);
}
status_t SurfaceComposerClient::setActiveColorMode(const sp<IBinder>& display,
ColorMode colorMode) {
- return ComposerService::getComposerService()->setActiveColorMode(display, colorMode);
+ binder::Status status = ComposerServiceAIDL::getComposerService()
+ ->setActiveColorMode(display, static_cast<int>(colorMode));
+ return statusTFromBinderStatus(status);
}
status_t SurfaceComposerClient::getBootDisplayModeSupport(bool* support) {
binder::Status status =
ComposerServiceAIDL::getComposerService()->getBootDisplayModeSupport(support);
- return status.transactionError();
+ return statusTFromBinderStatus(status);
+}
+
+status_t SurfaceComposerClient::getOverlaySupport(gui::OverlayProperties* outProperties) {
+ binder::Status status =
+ ComposerServiceAIDL::getComposerService()->getOverlaySupport(outProperties);
+ return statusTFromBinderStatus(status);
}
status_t SurfaceComposerClient::setBootDisplayMode(const sp<IBinder>& display,
ui::DisplayModeId displayModeId) {
- return ComposerService::getComposerService()->setBootDisplayMode(display, displayModeId);
+ binder::Status status = ComposerServiceAIDL::getComposerService()
+ ->setBootDisplayMode(display, static_cast<int>(displayModeId));
+ return statusTFromBinderStatus(status);
}
status_t SurfaceComposerClient::clearBootDisplayMode(const sp<IBinder>& display) {
binder::Status status =
ComposerServiceAIDL::getComposerService()->clearBootDisplayMode(display);
- return status.transactionError();
+ return statusTFromBinderStatus(status);
+}
+
+status_t SurfaceComposerClient::getHdrConversionCapabilities(
+ std::vector<gui::HdrConversionCapability>* hdrConversionCapabilities) {
+ binder::Status status = ComposerServiceAIDL::getComposerService()->getHdrConversionCapabilities(
+ hdrConversionCapabilities);
+ return statusTFromBinderStatus(status);
+}
+
+status_t SurfaceComposerClient::setHdrConversionStrategy(
+ gui::HdrConversionStrategy hdrConversionStrategy, ui::Hdr* outPreferredHdrOutputType) {
+ int hdrType;
+ binder::Status status = ComposerServiceAIDL::getComposerService()
+ ->setHdrConversionStrategy(hdrConversionStrategy, &hdrType);
+ *outPreferredHdrOutputType = static_cast<ui::Hdr>(hdrType);
+ return statusTFromBinderStatus(status);
+}
+
+status_t SurfaceComposerClient::getHdrOutputConversionSupport(bool* isSupported) {
+ binder::Status status =
+ ComposerServiceAIDL::getComposerService()->getHdrOutputConversionSupport(isSupported);
+ return statusTFromBinderStatus(status);
}
status_t SurfaceComposerClient::setOverrideFrameRate(uid_t uid, float frameRate) {
- return ComposerService::getComposerService()->setOverrideFrameRate(uid, frameRate);
+ binder::Status status =
+ ComposerServiceAIDL::getComposerService()->setOverrideFrameRate(uid, frameRate);
+ return statusTFromBinderStatus(status);
}
void SurfaceComposerClient::setAutoLowLatencyMode(const sp<IBinder>& display, bool on) {
@@ -2289,57 +2770,137 @@ void SurfaceComposerClient::setDisplayPowerMode(const sp<IBinder>& token,
status_t SurfaceComposerClient::getCompositionPreference(
ui::Dataspace* defaultDataspace, ui::PixelFormat* defaultPixelFormat,
ui::Dataspace* wideColorGamutDataspace, ui::PixelFormat* wideColorGamutPixelFormat) {
- return ComposerService::getComposerService()
- ->getCompositionPreference(defaultDataspace, defaultPixelFormat,
- wideColorGamutDataspace, wideColorGamutPixelFormat);
+ gui::CompositionPreference pref;
+ binder::Status status =
+ ComposerServiceAIDL::getComposerService()->getCompositionPreference(&pref);
+ if (status.isOk()) {
+ *defaultDataspace = static_cast<ui::Dataspace>(pref.defaultDataspace);
+ *defaultPixelFormat = static_cast<ui::PixelFormat>(pref.defaultPixelFormat);
+ *wideColorGamutDataspace = static_cast<ui::Dataspace>(pref.wideColorGamutDataspace);
+ *wideColorGamutPixelFormat = static_cast<ui::PixelFormat>(pref.wideColorGamutPixelFormat);
+ }
+ return statusTFromBinderStatus(status);
}
bool SurfaceComposerClient::getProtectedContentSupport() {
bool supported = false;
- ComposerService::getComposerService()->getProtectedContentSupport(&supported);
+ ComposerServiceAIDL::getComposerService()->getProtectedContentSupport(&supported);
return supported;
}
status_t SurfaceComposerClient::clearAnimationFrameStats() {
- return ComposerService::getComposerService()->clearAnimationFrameStats();
+ binder::Status status = ComposerServiceAIDL::getComposerService()->clearAnimationFrameStats();
+ return statusTFromBinderStatus(status);
}
status_t SurfaceComposerClient::getAnimationFrameStats(FrameStats* outStats) {
- return ComposerService::getComposerService()->getAnimationFrameStats(outStats);
+ gui::FrameStats stats;
+ binder::Status status =
+ ComposerServiceAIDL::getComposerService()->getAnimationFrameStats(&stats);
+ if (status.isOk()) {
+ outStats->refreshPeriodNano = stats.refreshPeriodNano;
+ outStats->desiredPresentTimesNano.setCapacity(stats.desiredPresentTimesNano.size());
+ for (const auto& t : stats.desiredPresentTimesNano) {
+ outStats->desiredPresentTimesNano.add(t);
+ }
+ outStats->actualPresentTimesNano.setCapacity(stats.actualPresentTimesNano.size());
+ for (const auto& t : stats.actualPresentTimesNano) {
+ outStats->actualPresentTimesNano.add(t);
+ }
+ outStats->frameReadyTimesNano.setCapacity(stats.frameReadyTimesNano.size());
+ for (const auto& t : stats.frameReadyTimesNano) {
+ outStats->frameReadyTimesNano.add(t);
+ }
+ }
+ return statusTFromBinderStatus(status);
}
status_t SurfaceComposerClient::overrideHdrTypes(const sp<IBinder>& display,
const std::vector<ui::Hdr>& hdrTypes) {
- return ComposerService::getComposerService()->overrideHdrTypes(display, hdrTypes);
+ std::vector<int32_t> hdrTypesVector;
+ hdrTypesVector.reserve(hdrTypes.size());
+ for (auto t : hdrTypes) {
+ hdrTypesVector.push_back(static_cast<int32_t>(t));
+ }
+
+ binder::Status status =
+ ComposerServiceAIDL::getComposerService()->overrideHdrTypes(display, hdrTypesVector);
+ return statusTFromBinderStatus(status);
}
status_t SurfaceComposerClient::onPullAtom(const int32_t atomId, std::string* outData,
bool* success) {
- return ComposerService::getComposerService()->onPullAtom(atomId, outData, success);
+ gui::PullAtomData pad;
+ binder::Status status = ComposerServiceAIDL::getComposerService()->onPullAtom(atomId, &pad);
+ if (status.isOk()) {
+ outData->assign(pad.data.begin(), pad.data.end());
+ *success = pad.success;
+ }
+ return statusTFromBinderStatus(status);
}
status_t SurfaceComposerClient::getDisplayedContentSamplingAttributes(const sp<IBinder>& display,
ui::PixelFormat* outFormat,
ui::Dataspace* outDataspace,
uint8_t* outComponentMask) {
- return ComposerService::getComposerService()
- ->getDisplayedContentSamplingAttributes(display, outFormat, outDataspace,
- outComponentMask);
+ if (!outFormat || !outDataspace || !outComponentMask) {
+ return BAD_VALUE;
+ }
+
+ gui::ContentSamplingAttributes attrs;
+ binder::Status status = ComposerServiceAIDL::getComposerService()
+ ->getDisplayedContentSamplingAttributes(display, &attrs);
+ if (status.isOk()) {
+ *outFormat = static_cast<ui::PixelFormat>(attrs.format);
+ *outDataspace = static_cast<ui::Dataspace>(attrs.dataspace);
+ *outComponentMask = static_cast<uint8_t>(attrs.componentMask);
+ }
+ return statusTFromBinderStatus(status);
}
status_t SurfaceComposerClient::setDisplayContentSamplingEnabled(const sp<IBinder>& display,
bool enable, uint8_t componentMask,
uint64_t maxFrames) {
- return ComposerService::getComposerService()->setDisplayContentSamplingEnabled(display, enable,
- componentMask,
- maxFrames);
+ binder::Status status =
+ ComposerServiceAIDL::getComposerService()
+ ->setDisplayContentSamplingEnabled(display, enable,
+ static_cast<int8_t>(componentMask),
+ static_cast<int64_t>(maxFrames));
+ return statusTFromBinderStatus(status);
}
status_t SurfaceComposerClient::getDisplayedContentSample(const sp<IBinder>& display,
uint64_t maxFrames, uint64_t timestamp,
DisplayedFrameStats* outStats) {
- return ComposerService::getComposerService()->getDisplayedContentSample(display, maxFrames,
- timestamp, outStats);
+ if (!outStats) {
+ return BAD_VALUE;
+ }
+
+ gui::DisplayedFrameStats stats;
+ binder::Status status =
+ ComposerServiceAIDL::getComposerService()->getDisplayedContentSample(display, maxFrames,
+ timestamp, &stats);
+ if (status.isOk()) {
+ // convert gui::DisplayedFrameStats to ui::DisplayedFrameStats
+ outStats->numFrames = static_cast<uint64_t>(stats.numFrames);
+ outStats->component_0_sample.reserve(stats.component_0_sample.size());
+ for (const auto& s : stats.component_0_sample) {
+ outStats->component_0_sample.push_back(static_cast<uint64_t>(s));
+ }
+ outStats->component_1_sample.reserve(stats.component_1_sample.size());
+ for (const auto& s : stats.component_1_sample) {
+ outStats->component_1_sample.push_back(static_cast<uint64_t>(s));
+ }
+ outStats->component_2_sample.reserve(stats.component_2_sample.size());
+ for (const auto& s : stats.component_2_sample) {
+ outStats->component_2_sample.push_back(static_cast<uint64_t>(s));
+ }
+ outStats->component_3_sample.reserve(stats.component_3_sample.size());
+ for (const auto& s : stats.component_3_sample) {
+ outStats->component_3_sample.push_back(static_cast<uint64_t>(s));
+ }
+ }
+ return statusTFromBinderStatus(status);
}
status_t SurfaceComposerClient::isWideColorDisplay(const sp<IBinder>& display,
@@ -2347,39 +2908,55 @@ status_t SurfaceComposerClient::isWideColorDisplay(const sp<IBinder>& display,
binder::Status status =
ComposerServiceAIDL::getComposerService()->isWideColorDisplay(display,
outIsWideColorDisplay);
- return status.transactionError();
+ return statusTFromBinderStatus(status);
}
status_t SurfaceComposerClient::addRegionSamplingListener(
const Rect& samplingArea, const sp<IBinder>& stopLayerHandle,
const sp<IRegionSamplingListener>& listener) {
- return ComposerService::getComposerService()->addRegionSamplingListener(samplingArea,
- stopLayerHandle,
- listener);
+ gui::ARect rect;
+ rect.left = samplingArea.left;
+ rect.top = samplingArea.top;
+ rect.right = samplingArea.right;
+ rect.bottom = samplingArea.bottom;
+ binder::Status status =
+ ComposerServiceAIDL::getComposerService()->addRegionSamplingListener(rect,
+ stopLayerHandle,
+ listener);
+ return statusTFromBinderStatus(status);
}
status_t SurfaceComposerClient::removeRegionSamplingListener(
const sp<IRegionSamplingListener>& listener) {
- return ComposerService::getComposerService()->removeRegionSamplingListener(listener);
+ binder::Status status =
+ ComposerServiceAIDL::getComposerService()->removeRegionSamplingListener(listener);
+ return statusTFromBinderStatus(status);
}
status_t SurfaceComposerClient::addFpsListener(int32_t taskId,
const sp<gui::IFpsListener>& listener) {
- return ComposerService::getComposerService()->addFpsListener(taskId, listener);
+ binder::Status status =
+ ComposerServiceAIDL::getComposerService()->addFpsListener(taskId, listener);
+ return statusTFromBinderStatus(status);
}
status_t SurfaceComposerClient::removeFpsListener(const sp<gui::IFpsListener>& listener) {
- return ComposerService::getComposerService()->removeFpsListener(listener);
+ binder::Status status = ComposerServiceAIDL::getComposerService()->removeFpsListener(listener);
+ return statusTFromBinderStatus(status);
}
status_t SurfaceComposerClient::addTunnelModeEnabledListener(
const sp<gui::ITunnelModeEnabledListener>& listener) {
- return ComposerService::getComposerService()->addTunnelModeEnabledListener(listener);
+ binder::Status status =
+ ComposerServiceAIDL::getComposerService()->addTunnelModeEnabledListener(listener);
+ return statusTFromBinderStatus(status);
}
status_t SurfaceComposerClient::removeTunnelModeEnabledListener(
const sp<gui::ITunnelModeEnabledListener>& listener) {
- return ComposerService::getComposerService()->removeTunnelModeEnabledListener(listener);
+ binder::Status status =
+ ComposerServiceAIDL::getComposerService()->removeTunnelModeEnabledListener(listener);
+ return statusTFromBinderStatus(status);
}
bool SurfaceComposerClient::getDisplayBrightnessSupport(const sp<IBinder>& displayToken) {
@@ -2395,7 +2972,7 @@ status_t SurfaceComposerClient::setDisplayBrightness(const sp<IBinder>& displayT
binder::Status status =
ComposerServiceAIDL::getComposerService()->setDisplayBrightness(displayToken,
brightness);
- return status.transactionError();
+ return statusTFromBinderStatus(status);
}
status_t SurfaceComposerClient::addHdrLayerInfoListener(
@@ -2403,7 +2980,7 @@ status_t SurfaceComposerClient::addHdrLayerInfoListener(
binder::Status status =
ComposerServiceAIDL::getComposerService()->addHdrLayerInfoListener(displayToken,
listener);
- return status.transactionError();
+ return statusTFromBinderStatus(status);
}
status_t SurfaceComposerClient::removeHdrLayerInfoListener(
@@ -2411,45 +2988,79 @@ status_t SurfaceComposerClient::removeHdrLayerInfoListener(
binder::Status status =
ComposerServiceAIDL::getComposerService()->removeHdrLayerInfoListener(displayToken,
listener);
- return status.transactionError();
+ return statusTFromBinderStatus(status);
}
status_t SurfaceComposerClient::notifyPowerBoost(int32_t boostId) {
binder::Status status = ComposerServiceAIDL::getComposerService()->notifyPowerBoost(boostId);
- return status.transactionError();
+ return statusTFromBinderStatus(status);
}
status_t SurfaceComposerClient::setGlobalShadowSettings(const half4& ambientColor,
const half4& spotColor, float lightPosY,
float lightPosZ, float lightRadius) {
- return ComposerService::getComposerService()->setGlobalShadowSettings(ambientColor, spotColor,
- lightPosY, lightPosZ,
- lightRadius);
+ gui::Color ambientColorG, spotColorG;
+ ambientColorG.r = ambientColor.r;
+ ambientColorG.g = ambientColor.g;
+ ambientColorG.b = ambientColor.b;
+ ambientColorG.a = ambientColor.a;
+ spotColorG.r = spotColor.r;
+ spotColorG.g = spotColor.g;
+ spotColorG.b = spotColor.b;
+ spotColorG.a = spotColor.a;
+ binder::Status status =
+ ComposerServiceAIDL::getComposerService()->setGlobalShadowSettings(ambientColorG,
+ spotColorG,
+ lightPosY, lightPosZ,
+ lightRadius);
+ return statusTFromBinderStatus(status);
}
std::optional<DisplayDecorationSupport> SurfaceComposerClient::getDisplayDecorationSupport(
const sp<IBinder>& displayToken) {
+ std::optional<gui::DisplayDecorationSupport> gsupport;
+ binder::Status status =
+ ComposerServiceAIDL::getComposerService()->getDisplayDecorationSupport(displayToken,
+ &gsupport);
std::optional<DisplayDecorationSupport> support;
- ComposerService::getComposerService()->getDisplayDecorationSupport(displayToken, &support);
+ if (status.isOk() && gsupport.has_value()) {
+ support.emplace(DisplayDecorationSupport{
+ .format =
+ static_cast<aidl::android::hardware::graphics::common::PixelFormat>(
+ gsupport->format),
+ .alphaInterpretation =
+ static_cast<aidl::android::hardware::graphics::common::AlphaInterpretation>(
+ gsupport->alphaInterpretation)
+ });
+ }
return support;
}
-int SurfaceComposerClient::getGPUContextPriority() {
- return ComposerService::getComposerService()->getGPUContextPriority();
+int SurfaceComposerClient::getGpuContextPriority() {
+ int priority;
+ binder::Status status =
+ ComposerServiceAIDL::getComposerService()->getGpuContextPriority(&priority);
+ if (!status.isOk()) {
+ status_t err = statusTFromBinderStatus(status);
+ ALOGE("getGpuContextPriority failed to read data: %s (%d)", strerror(-err), err);
+ return 0;
+ }
+ return priority;
}
status_t SurfaceComposerClient::addWindowInfosListener(
const sp<WindowInfosListener>& windowInfosListener,
std::pair<std::vector<gui::WindowInfo>, std::vector<gui::DisplayInfo>>* outInitialInfo) {
return WindowInfosListenerReporter::getInstance()
- ->addWindowInfosListener(windowInfosListener, ComposerService::getComposerService(),
+ ->addWindowInfosListener(windowInfosListener, ComposerServiceAIDL::getComposerService(),
outInitialInfo);
}
status_t SurfaceComposerClient::removeWindowInfosListener(
const sp<WindowInfosListener>& windowInfosListener) {
return WindowInfosListenerReporter::getInstance()
- ->removeWindowInfosListener(windowInfosListener, ComposerService::getComposerService());
+ ->removeWindowInfosListener(windowInfosListener,
+ ComposerServiceAIDL::getComposerService());
}
// ----------------------------------------------------------------------------
@@ -2460,7 +3071,7 @@ status_t ScreenshotClient::captureDisplay(const DisplayCaptureArgs& captureArgs,
if (s == nullptr) return NO_INIT;
binder::Status status = s->captureDisplay(captureArgs, captureListener);
- return status.transactionError();
+ return statusTFromBinderStatus(status);
}
status_t ScreenshotClient::captureDisplay(DisplayId displayId,
@@ -2469,7 +3080,7 @@ status_t ScreenshotClient::captureDisplay(DisplayId displayId,
if (s == nullptr) return NO_INIT;
binder::Status status = s->captureDisplayById(displayId.value, captureListener);
- return status.transactionError();
+ return statusTFromBinderStatus(status);
}
status_t ScreenshotClient::captureLayers(const LayerCaptureArgs& captureArgs,
@@ -2478,7 +3089,7 @@ status_t ScreenshotClient::captureLayers(const LayerCaptureArgs& captureArgs,
if (s == nullptr) return NO_INIT;
binder::Status status = s->captureLayers(captureArgs, captureListener);
- return status.transactionError();
+ return statusTFromBinderStatus(status);
}
// ---------------------------------------------------------------------------------
@@ -2501,6 +3112,7 @@ void ReleaseCallbackThread::threadMain() {
while (true) {
{
std::unique_lock<std::mutex> lock(mMutex);
+ base::ScopedLockAssertion assumeLocked(mMutex);
callbackInfos = std::move(mCallbackInfos);
mCallbackInfos = {};
}
@@ -2513,6 +3125,7 @@ void ReleaseCallbackThread::threadMain() {
{
std::unique_lock<std::mutex> lock(mMutex);
+ base::ScopedLockAssertion assumeLocked(mMutex);
if (mCallbackInfos.size() == 0) {
mReleaseCallbackPending.wait(lock);
}
diff --git a/libs/gui/SurfaceControl.cpp b/libs/gui/SurfaceControl.cpp
index 654fb336fe..c5f9c38ca3 100644
--- a/libs/gui/SurfaceControl.cpp
+++ b/libs/gui/SurfaceControl.cpp
@@ -26,6 +26,7 @@
#include <utils/Errors.h>
#include <utils/KeyedVector.h>
#include <utils/Log.h>
+#include <utils/Looper.h>
#include <utils/threads.h>
#include <binder/IPCThreadState.h>
@@ -34,8 +35,9 @@
#include <ui/Rect.h>
#include <ui/StaticDisplayInfo.h>
-#include <gui/BufferQueueCore.h>
#include <gui/BLASTBufferQueue.h>
+#include <gui/BufferQueueCore.h>
+#include <gui/Choreographer.h>
#include <gui/ISurfaceComposer.h>
#include <gui/Surface.h>
#include <gui/SurfaceComposerClient.h>
@@ -49,13 +51,12 @@ namespace android {
// ============================================================================
SurfaceControl::SurfaceControl(const sp<SurfaceComposerClient>& client, const sp<IBinder>& handle,
- const sp<IGraphicBufferProducer>& gbp, int32_t layerId,
- uint32_t w, uint32_t h, PixelFormat format, uint32_t transform,
- uint32_t flags)
+ int32_t layerId, const std::string& name, uint32_t w, uint32_t h,
+ PixelFormat format, uint32_t transform, uint32_t flags)
: mClient(client),
mHandle(handle),
- mGraphicBufferProducer(gbp),
mLayerId(layerId),
+ mName(name),
mTransformHint(transform),
mWidth(w),
mHeight(h),
@@ -65,9 +66,9 @@ SurfaceControl::SurfaceControl(const sp<SurfaceComposerClient>& client, const sp
SurfaceControl::SurfaceControl(const sp<SurfaceControl>& other) {
mClient = other->mClient;
mHandle = other->mHandle;
- mGraphicBufferProducer = other->mGraphicBufferProducer;
mTransformHint = other->mTransformHint;
mLayerId = other->mLayerId;
+ mName = other->mName;
mWidth = other->mWidth;
mHeight = other->mHeight;
mFormat = other->mFormat;
@@ -165,11 +166,11 @@ sp<Surface> SurfaceControl::createSurface()
void SurfaceControl::updateDefaultBufferSize(uint32_t width, uint32_t height) {
Mutex::Autolock _l(mLock);
- mWidth = width; mHeight = height;
+ mWidth = width;
+ mHeight = height;
if (mBbq) {
mBbq->update(mBbqChild, width, height, mFormat);
}
-
}
sp<IBinder> SurfaceControl::getLayerStateHandle() const
@@ -188,6 +189,28 @@ int32_t SurfaceControl::getLayerId() const {
return mLayerId;
}
+const std::string& SurfaceControl::getName() const {
+ return mName;
+}
+
+std::shared_ptr<Choreographer> SurfaceControl::getChoreographer() {
+ if (mChoreographer) {
+ return mChoreographer;
+ }
+ sp<Looper> looper = Looper::getForThread();
+ if (!looper.get()) {
+ ALOGE("%s: No looper prepared for thread", __func__);
+ return nullptr;
+ }
+ mChoreographer = std::make_shared<Choreographer>(looper, getHandle());
+ status_t result = mChoreographer->initialize();
+ if (result != OK) {
+ ALOGE("Failed to initialize choreographer");
+ mChoreographer = nullptr;
+ }
+ return mChoreographer;
+}
+
sp<IGraphicBufferProducer> SurfaceControl::getIGraphicBufferProducer()
{
getSurface();
@@ -215,6 +238,7 @@ status_t SurfaceControl::writeToParcel(Parcel& parcel) {
SAFE_PARCEL(parcel.writeStrongBinder, ISurfaceComposerClient::asBinder(mClient->getClient()));
SAFE_PARCEL(parcel.writeStrongBinder, mHandle);
SAFE_PARCEL(parcel.writeInt32, mLayerId);
+ SAFE_PARCEL(parcel.writeUtf8AsUtf16, mName);
SAFE_PARCEL(parcel.writeUint32, mTransformHint);
SAFE_PARCEL(parcel.writeUint32, mWidth);
SAFE_PARCEL(parcel.writeUint32, mHeight);
@@ -228,6 +252,7 @@ status_t SurfaceControl::readFromParcel(const Parcel& parcel,
sp<IBinder> client;
sp<IBinder> handle;
int32_t layerId;
+ std::string layerName;
uint32_t transformHint;
uint32_t width;
uint32_t height;
@@ -236,18 +261,17 @@ status_t SurfaceControl::readFromParcel(const Parcel& parcel,
SAFE_PARCEL(parcel.readStrongBinder, &client);
SAFE_PARCEL(parcel.readStrongBinder, &handle);
SAFE_PARCEL(parcel.readInt32, &layerId);
+ SAFE_PARCEL(parcel.readUtf8FromUtf16, &layerName);
SAFE_PARCEL(parcel.readUint32, &transformHint);
SAFE_PARCEL(parcel.readUint32, &width);
SAFE_PARCEL(parcel.readUint32, &height);
SAFE_PARCEL(parcel.readUint32, &format);
// We aren't the original owner of the surface.
- *outSurfaceControl =
- new SurfaceControl(new SurfaceComposerClient(
- interface_cast<ISurfaceComposerClient>(client)),
- handle.get(), nullptr, layerId,
- width, height, format,
- transformHint);
+ *outSurfaceControl = new SurfaceControl(new SurfaceComposerClient(
+ interface_cast<ISurfaceComposerClient>(client)),
+ handle.get(), layerId, layerName, width, height, format,
+ transformHint);
return NO_ERROR;
}
diff --git a/libs/gui/SyncFeatures.cpp b/libs/gui/SyncFeatures.cpp
index 1a8fc1a00a..2d863c2585 100644
--- a/libs/gui/SyncFeatures.cpp
+++ b/libs/gui/SyncFeatures.cpp
@@ -36,8 +36,12 @@ SyncFeatures::SyncFeatures() : Singleton<SyncFeatures>(),
mHasFenceSync(false),
mHasWaitSync(false) {
EGLDisplay dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
- // This can only be called after EGL has been initialized; otherwise the
- // check below will abort.
+ // eglQueryString can only be called after EGL has been initialized;
+ // otherwise the check below will abort. If RenderEngine is using SkiaVk,
+ // EGL will not have been initialized. There's no problem with initializing
+ // it again here (it is ref counted), and then terminating it later.
+ EGLBoolean initialized = eglInitialize(dpy, nullptr, nullptr);
+ LOG_ALWAYS_FATAL_IF(!initialized, "eglInitialize failed");
const char* exts = eglQueryString(dpy, EGL_EXTENSIONS);
LOG_ALWAYS_FATAL_IF(exts == nullptr, "eglQueryString failed");
if (strstr(exts, "EGL_ANDROID_native_fence_sync")) {
@@ -63,6 +67,8 @@ SyncFeatures::SyncFeatures() : Singleton<SyncFeatures>(),
mString.append(" EGL_KHR_wait_sync");
}
mString.append("]");
+ // Terminate EGL to match the eglInitialize above
+ eglTerminate(dpy);
}
bool SyncFeatures::useNativeFenceSync() const {
diff --git a/libs/gui/TEST_MAPPING b/libs/gui/TEST_MAPPING
index 1c435304a8..941503548d 100644
--- a/libs/gui/TEST_MAPPING
+++ b/libs/gui/TEST_MAPPING
@@ -3,5 +3,11 @@
{
"path": "frameworks/native/libs/nativewindow"
}
+ ],
+ "postsubmit": [
+ {
+ // TODO(257123981): move this to presubmit after dealing with existing breakages.
+ "name": "libgui_test"
+ }
]
}
diff --git a/libs/gui/TransactionTracing.cpp b/libs/gui/TransactionTracing.cpp
deleted file mode 100644
index eedc3df009..0000000000
--- a/libs/gui/TransactionTracing.cpp
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "gui/TransactionTracing.h"
-#include "gui/ISurfaceComposer.h"
-
-#include <private/gui/ComposerService.h>
-
-namespace android {
-
-sp<TransactionTraceListener> TransactionTraceListener::sInstance = nullptr;
-std::mutex TransactionTraceListener::sMutex;
-
-TransactionTraceListener::TransactionTraceListener() {}
-
-sp<TransactionTraceListener> TransactionTraceListener::getInstance() {
- const std::lock_guard<std::mutex> lock(sMutex);
-
- if (sInstance == nullptr) {
- sInstance = new TransactionTraceListener;
-
- sp<ISurfaceComposer> sf(ComposerService::getComposerService());
- sf->addTransactionTraceListener(sInstance);
- }
-
- return sInstance;
-}
-
-binder::Status TransactionTraceListener::onToggled(bool enabled) {
- ALOGD("TransactionTraceListener: onToggled listener called");
- mTracingEnabled = enabled;
-
- return binder::Status::ok();
-}
-
-bool TransactionTraceListener::isTracingEnabled() {
- return mTracingEnabled;
-}
-
-} // namespace android \ No newline at end of file
diff --git a/libs/gui/VsyncEventData.cpp b/libs/gui/VsyncEventData.cpp
index 23f0921e99..8e00c2fe32 100644
--- a/libs/gui/VsyncEventData.cpp
+++ b/libs/gui/VsyncEventData.cpp
@@ -23,6 +23,9 @@
namespace android::gui {
+static_assert(VsyncEventData::kFrameTimelinesCapacity == 7,
+ "Must update value in DisplayEventReceiver.java#FRAME_TIMELINES_CAPACITY (and here)");
+
int64_t VsyncEventData::preferredVsyncId() const {
return frameTimelines[preferredFrameTimelineIndex].vsyncId;
}
@@ -43,11 +46,15 @@ status_t ParcelableVsyncEventData::readFromParcel(const Parcel* parcel) {
SAFE_PARCEL(parcel->readInt64, &vsync.frameInterval);
- uint64_t uintPreferredFrameTimelineIndex;
- SAFE_PARCEL(parcel->readUint64, &uintPreferredFrameTimelineIndex);
+ uint32_t uintPreferredFrameTimelineIndex;
+ SAFE_PARCEL(parcel->readUint32, &uintPreferredFrameTimelineIndex);
vsync.preferredFrameTimelineIndex = static_cast<size_t>(uintPreferredFrameTimelineIndex);
- for (int i = 0; i < VsyncEventData::kFrameTimelinesLength; i++) {
+ uint32_t uintFrameTimelinesLength;
+ SAFE_PARCEL(parcel->readUint32, &uintFrameTimelinesLength);
+ vsync.frameTimelinesLength = static_cast<size_t>(uintFrameTimelinesLength);
+
+ for (size_t i = 0; i < vsync.frameTimelinesLength; i++) {
SAFE_PARCEL(parcel->readInt64, &vsync.frameTimelines[i].vsyncId);
SAFE_PARCEL(parcel->readInt64, &vsync.frameTimelines[i].deadlineTimestamp);
SAFE_PARCEL(parcel->readInt64, &vsync.frameTimelines[i].expectedPresentationTime);
@@ -57,8 +64,9 @@ status_t ParcelableVsyncEventData::readFromParcel(const Parcel* parcel) {
}
status_t ParcelableVsyncEventData::writeToParcel(Parcel* parcel) const {
SAFE_PARCEL(parcel->writeInt64, vsync.frameInterval);
- SAFE_PARCEL(parcel->writeUint64, vsync.preferredFrameTimelineIndex);
- for (int i = 0; i < VsyncEventData::kFrameTimelinesLength; i++) {
+ SAFE_PARCEL(parcel->writeUint32, vsync.preferredFrameTimelineIndex);
+ SAFE_PARCEL(parcel->writeUint32, vsync.frameTimelinesLength);
+ for (size_t i = 0; i < vsync.frameTimelinesLength; i++) {
SAFE_PARCEL(parcel->writeInt64, vsync.frameTimelines[i].vsyncId);
SAFE_PARCEL(parcel->writeInt64, vsync.frameTimelines[i].deadlineTimestamp);
SAFE_PARCEL(parcel->writeInt64, vsync.frameTimelines[i].expectedPresentationTime);
diff --git a/libs/gui/WindowInfo.cpp b/libs/gui/WindowInfo.cpp
index 4e966d1393..6df9ff1664 100644
--- a/libs/gui/WindowInfo.cpp
+++ b/libs/gui/WindowInfo.cpp
@@ -76,7 +76,7 @@ bool WindowInfo::operator==(const WindowInfo& info) const {
info.inputConfig == inputConfig && info.displayId == displayId &&
info.replaceTouchableRegionWithCrop == replaceTouchableRegionWithCrop &&
info.applicationInfo == applicationInfo && info.layoutParamsType == layoutParamsType &&
- info.layoutParamsFlags == layoutParamsFlags && info.isClone == isClone;
+ info.layoutParamsFlags == layoutParamsFlags;
}
status_t WindowInfo::writeToParcel(android::Parcel* parcel) const {
@@ -124,8 +124,8 @@ status_t WindowInfo::writeToParcel(android::Parcel* parcel) const {
parcel->write(touchableRegion) ?:
parcel->writeBool(replaceTouchableRegionWithCrop) ?:
parcel->writeStrongBinder(touchableRegionCropHandle.promote()) ?:
- parcel->writeStrongBinder(windowToken) ?:
- parcel->writeBool(isClone);
+ parcel->writeStrongBinder(windowToken);
+ parcel->writeStrongBinder(focusTransferTarget);
// clang-format on
return status;
}
@@ -177,7 +177,8 @@ status_t WindowInfo::readFromParcel(const android::Parcel* parcel) {
parcel->readBool(&replaceTouchableRegionWithCrop) ?:
parcel->readNullableStrongBinder(&touchableRegionCropHandleSp) ?:
parcel->readNullableStrongBinder(&windowToken) ?:
- parcel->readBool(&isClone);
+ parcel->readNullableStrongBinder(&focusTransferTarget);
+
// clang-format on
if (status != OK) {
diff --git a/libs/gui/WindowInfosListenerReporter.cpp b/libs/gui/WindowInfosListenerReporter.cpp
index cfc7dbc463..0929b8e120 100644
--- a/libs/gui/WindowInfosListenerReporter.cpp
+++ b/libs/gui/WindowInfosListenerReporter.cpp
@@ -14,15 +14,17 @@
* limitations under the License.
*/
-#include <gui/ISurfaceComposer.h>
+#include <android/gui/ISurfaceComposer.h>
+#include <gui/AidlStatusUtil.h>
#include <gui/WindowInfosListenerReporter.h>
+#include "gui/WindowInfosUpdate.h"
namespace android {
using gui::DisplayInfo;
-using gui::IWindowInfosReportedListener;
using gui::WindowInfo;
using gui::WindowInfosListener;
+using gui::aidl_utils::statusTFromBinderStatus;
sp<WindowInfosListenerReporter> WindowInfosListenerReporter::getInstance() {
static sp<WindowInfosListenerReporter> sInstance = new WindowInfosListenerReporter;
@@ -31,13 +33,19 @@ sp<WindowInfosListenerReporter> WindowInfosListenerReporter::getInstance() {
status_t WindowInfosListenerReporter::addWindowInfosListener(
const sp<WindowInfosListener>& windowInfosListener,
- const sp<ISurfaceComposer>& surfaceComposer,
+ const sp<gui::ISurfaceComposer>& surfaceComposer,
std::pair<std::vector<gui::WindowInfo>, std::vector<gui::DisplayInfo>>* outInitialInfo) {
status_t status = OK;
{
std::scoped_lock lock(mListenersMutex);
if (mWindowInfosListeners.empty()) {
- status = surfaceComposer->addWindowInfosListener(this);
+ gui::WindowInfosListenerInfo listenerInfo;
+ binder::Status s = surfaceComposer->addWindowInfosListener(this, &listenerInfo);
+ status = statusTFromBinderStatus(s);
+ if (status == OK) {
+ mWindowInfosPublisher = std::move(listenerInfo.windowInfosPublisher);
+ mListenerId = listenerInfo.listenerId;
+ }
}
if (status == OK) {
@@ -55,12 +63,17 @@ status_t WindowInfosListenerReporter::addWindowInfosListener(
status_t WindowInfosListenerReporter::removeWindowInfosListener(
const sp<WindowInfosListener>& windowInfosListener,
- const sp<ISurfaceComposer>& surfaceComposer) {
+ const sp<gui::ISurfaceComposer>& surfaceComposer) {
status_t status = OK;
{
std::scoped_lock lock(mListenersMutex);
+ if (mWindowInfosListeners.find(windowInfosListener) == mWindowInfosListeners.end()) {
+ return status;
+ }
+
if (mWindowInfosListeners.size() == 1) {
- status = surfaceComposer->removeWindowInfosListener(this);
+ binder::Status s = surfaceComposer->removeWindowInfosListener(this);
+ status = statusTFromBinderStatus(s);
// Clear the last stored state since we're disabling updates and don't want to hold
// stale values
mLastWindowInfos.clear();
@@ -76,9 +89,9 @@ status_t WindowInfosListenerReporter::removeWindowInfosListener(
}
binder::Status WindowInfosListenerReporter::onWindowInfosChanged(
- const std::vector<WindowInfo>& windowInfos, const std::vector<DisplayInfo>& displayInfos,
- const sp<IWindowInfosReportedListener>& windowInfosReportedListener) {
- std::unordered_set<sp<WindowInfosListener>, SpHash<WindowInfosListener>> windowInfosListeners;
+ const gui::WindowInfosUpdate& update) {
+ std::unordered_set<sp<WindowInfosListener>, gui::SpHash<WindowInfosListener>>
+ windowInfosListeners;
{
std::scoped_lock lock(mListenersMutex);
@@ -86,25 +99,26 @@ binder::Status WindowInfosListenerReporter::onWindowInfosChanged(
windowInfosListeners.insert(listener);
}
- mLastWindowInfos = windowInfos;
- mLastDisplayInfos = displayInfos;
+ mLastWindowInfos = update.windowInfos;
+ mLastDisplayInfos = update.displayInfos;
}
for (auto listener : windowInfosListeners) {
- listener->onWindowInfosChanged(windowInfos, displayInfos);
+ listener->onWindowInfosChanged(update);
}
- if (windowInfosReportedListener) {
- windowInfosReportedListener->onWindowInfosReported();
- }
+ mWindowInfosPublisher->ackWindowInfosReceived(update.vsyncId, mListenerId);
return binder::Status::ok();
}
-void WindowInfosListenerReporter::reconnect(const sp<ISurfaceComposer>& composerService) {
+void WindowInfosListenerReporter::reconnect(const sp<gui::ISurfaceComposer>& composerService) {
std::scoped_lock lock(mListenersMutex);
if (!mWindowInfosListeners.empty()) {
- composerService->addWindowInfosListener(this);
+ gui::WindowInfosListenerInfo listenerInfo;
+ composerService->addWindowInfosListener(this, &listenerInfo);
+ mWindowInfosPublisher = std::move(listenerInfo.windowInfosPublisher);
+ mListenerId = listenerInfo.listenerId;
}
}
diff --git a/libs/gui/WindowInfosUpdate.cpp b/libs/gui/WindowInfosUpdate.cpp
new file mode 100644
index 0000000000..38ae5ef102
--- /dev/null
+++ b/libs/gui/WindowInfosUpdate.cpp
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <gui/WindowInfosUpdate.h>
+#include <private/gui/ParcelUtils.h>
+
+namespace android::gui {
+
+status_t WindowInfosUpdate::readFromParcel(const android::Parcel* parcel) {
+ if (parcel == nullptr) {
+ ALOGE("%s: Null parcel", __func__);
+ return BAD_VALUE;
+ }
+
+ uint32_t size;
+
+ SAFE_PARCEL(parcel->readUint32, &size);
+ windowInfos.reserve(size);
+ for (uint32_t i = 0; i < size; i++) {
+ windowInfos.push_back({});
+ SAFE_PARCEL(windowInfos.back().readFromParcel, parcel);
+ }
+
+ SAFE_PARCEL(parcel->readUint32, &size);
+ displayInfos.reserve(size);
+ for (uint32_t i = 0; i < size; i++) {
+ displayInfos.push_back({});
+ SAFE_PARCEL(displayInfos.back().readFromParcel, parcel);
+ }
+
+ SAFE_PARCEL(parcel->readInt64, &vsyncId);
+ SAFE_PARCEL(parcel->readInt64, &timestamp);
+
+ return OK;
+}
+
+status_t WindowInfosUpdate::writeToParcel(android::Parcel* parcel) const {
+ if (parcel == nullptr) {
+ ALOGE("%s: Null parcel", __func__);
+ return BAD_VALUE;
+ }
+
+ SAFE_PARCEL(parcel->writeUint32, static_cast<uint32_t>(windowInfos.size()));
+ for (auto& windowInfo : windowInfos) {
+ SAFE_PARCEL(windowInfo.writeToParcel, parcel);
+ }
+
+ SAFE_PARCEL(parcel->writeUint32, static_cast<uint32_t>(displayInfos.size()));
+ for (auto& displayInfo : displayInfos) {
+ SAFE_PARCEL(displayInfo.writeToParcel, parcel);
+ }
+
+ SAFE_PARCEL(parcel->writeInt64, vsyncId);
+ SAFE_PARCEL(parcel->writeInt64, timestamp);
+
+ return OK;
+}
+
+} // namespace android::gui
diff --git a/libs/gui/aidl/android/gui/Rect.aidl b/libs/gui/aidl/android/gui/ARect.aidl
index 1b13761392..5785907a9c 100644
--- a/libs/gui/aidl/android/gui/Rect.aidl
+++ b/libs/gui/aidl/android/gui/ARect.aidl
@@ -20,7 +20,7 @@ package android.gui;
// TODO(b/221473398):
// use hardware/interfaces/graphics/common/aidl/android/hardware/graphics/common/Rect.aidl
/** @hide */
-parcelable Rect {
+parcelable ARect {
/// Minimum X coordinate of the rectangle.
int left;
diff --git a/libs/gui/aidl/android/gui/CachingHint.aidl b/libs/gui/aidl/android/gui/CachingHint.aidl
new file mode 100644
index 0000000000..b35c79547f
--- /dev/null
+++ b/libs/gui/aidl/android/gui/CachingHint.aidl
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.gui;
+
+/*
+ * Hint for configuring caching behavior for a layer
+ * @hide
+ */
+@Backing(type="int")
+enum CachingHint {
+ // Caching is disabled. A layer may explicitly disable caching for
+ // improving image quality for some scenes.
+ Disabled = 0,
+ // Caching is enabled. A layer is cacheable by default.
+ Enabled = 1
+}
diff --git a/libs/gui/aidl/android/gui/Color.aidl b/libs/gui/aidl/android/gui/Color.aidl
new file mode 100644
index 0000000000..12af066562
--- /dev/null
+++ b/libs/gui/aidl/android/gui/Color.aidl
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.gui;
+
+/** @hide */
+parcelable Color {
+ float r;
+ float g;
+ float b;
+ float a;
+}
diff --git a/libs/gui/aidl/android/gui/CompositionPreference.aidl b/libs/gui/aidl/android/gui/CompositionPreference.aidl
new file mode 100644
index 0000000000..b615824a7d
--- /dev/null
+++ b/libs/gui/aidl/android/gui/CompositionPreference.aidl
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.gui;
+
+/** @hide */
+parcelable CompositionPreference {
+ int /*ui::Dataspace*/ defaultDataspace;
+ int /*ui::PixelFormat*/ defaultPixelFormat;
+ int /*ui::Dataspace*/ wideColorGamutDataspace;
+ int /*ui::PixelFormat*/ wideColorGamutPixelFormat;
+}
diff --git a/libs/gui/aidl/android/gui/ContentSamplingAttributes.aidl b/libs/gui/aidl/android/gui/ContentSamplingAttributes.aidl
new file mode 100644
index 0000000000..5d913b1da6
--- /dev/null
+++ b/libs/gui/aidl/android/gui/ContentSamplingAttributes.aidl
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.gui;
+
+/** @hide */
+parcelable ContentSamplingAttributes {
+ int /*ui::PixelFormat*/ format;
+ int /*ui::Dataspace*/ dataspace;
+ byte componentMask;
+}
diff --git a/libs/gui/aidl/android/gui/CreateSurfaceResult.aidl b/libs/gui/aidl/android/gui/CreateSurfaceResult.aidl
new file mode 100644
index 0000000000..eea12dc75d
--- /dev/null
+++ b/libs/gui/aidl/android/gui/CreateSurfaceResult.aidl
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.gui;
+
+/** @hide */
+parcelable CreateSurfaceResult {
+ IBinder handle;
+ int layerId;
+ String layerName;
+ int transformHint;
+}
diff --git a/libs/gui/aidl/android/gui/DeviceProductInfo.aidl b/libs/gui/aidl/android/gui/DeviceProductInfo.aidl
new file mode 100644
index 0000000000..98404cf0fd
--- /dev/null
+++ b/libs/gui/aidl/android/gui/DeviceProductInfo.aidl
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.gui;
+
+// Product-specific information about the display or the directly connected device on the
+// display chain. For example, if the display is transitively connected, this field may contain
+// product information about the intermediate device.
+
+/** @hide */
+parcelable DeviceProductInfo {
+ parcelable ModelYear {
+ int year;
+ }
+
+ parcelable ManufactureYear {
+ ModelYear modelYear;
+ }
+
+ parcelable ManufactureWeekAndYear {
+ ManufactureYear manufactureYear;
+
+ // 1-base week number. Week numbering may not be consistent between manufacturers.
+ int week;
+ }
+
+ union ManufactureOrModelDate {
+ ModelYear modelYear;
+ ManufactureYear manufactureYear;
+ ManufactureWeekAndYear manufactureWeekAndYear;
+ }
+
+ // Display name.
+ @utf8InCpp String name;
+
+ // NULL-terminated Manufacturer plug and play ID.
+ byte[] manufacturerPnpId;
+
+ // Manufacturer product ID.
+ @utf8InCpp String productId;
+
+ ManufactureOrModelDate manufactureOrModelDate;
+
+ byte[] relativeAddress;
+}
diff --git a/libs/gui/aidl/android/gui/DisplayConnectionType.aidl b/libs/gui/aidl/android/gui/DisplayConnectionType.aidl
new file mode 100644
index 0000000000..72c4ede7ac
--- /dev/null
+++ b/libs/gui/aidl/android/gui/DisplayConnectionType.aidl
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.gui;
+
+/** @hide */
+@Backing(type="int")
+enum DisplayConnectionType {
+ Internal = 0,
+ External = 1
+}
diff --git a/libs/gui/aidl/android/gui/DisplayDecorationSupport.aidl b/libs/gui/aidl/android/gui/DisplayDecorationSupport.aidl
new file mode 100644
index 0000000000..023049657b
--- /dev/null
+++ b/libs/gui/aidl/android/gui/DisplayDecorationSupport.aidl
@@ -0,0 +1,25 @@
+/**
+ * Copyright (c) 2022, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.gui;
+
+// TODO(b/222607970):
+// remove this aidl and use android.hardware.graphics.common.DisplayDecorationSupport
+/** @hide */
+parcelable DisplayDecorationSupport {
+ int format;
+ int alphaInterpretation;
+}
diff --git a/libs/gui/aidl/android/gui/DisplayMode.aidl b/libs/gui/aidl/android/gui/DisplayMode.aidl
new file mode 100644
index 0000000000..ce30426cb5
--- /dev/null
+++ b/libs/gui/aidl/android/gui/DisplayMode.aidl
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.gui;
+
+import android.gui.Size;
+
+// Mode supported by physical display.
+// Make sure to sync with libui DisplayMode.h
+
+/** @hide */
+parcelable DisplayMode {
+ int id;
+ Size resolution;
+ float xDpi = 0.0f;
+ float yDpi = 0.0f;
+ int[] supportedHdrTypes;
+
+ float refreshRate = 0.0f;
+ long appVsyncOffset = 0;
+ long sfVsyncOffset = 0;
+ long presentationDeadline = 0;
+ int group = -1;
+}
diff --git a/libs/gui/aidl/android/gui/DisplayModeSpecs.aidl b/libs/gui/aidl/android/gui/DisplayModeSpecs.aidl
new file mode 100644
index 0000000000..af138c7539
--- /dev/null
+++ b/libs/gui/aidl/android/gui/DisplayModeSpecs.aidl
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.gui;
+
+/** @hide */
+parcelable DisplayModeSpecs {
+ /**
+ * Defines the refresh rates ranges that should be used by SF.
+ */
+ parcelable RefreshRateRanges {
+ /**
+ * Defines a range of refresh rates.
+ */
+ parcelable RefreshRateRange {
+ float min;
+ float max;
+ }
+
+ /**
+ * The range of refresh rates that the display should run at.
+ */
+ RefreshRateRange physical;
+
+ /**
+ * The range of refresh rates that apps should render at.
+ */
+ RefreshRateRange render;
+ }
+
+ /**
+ * Base mode ID. This is what system defaults to for all other settings, or
+ * if the refresh rate range is not available.
+ */
+ int defaultMode;
+
+ /**
+ * If true this will allow switching between modes in different display configuration
+ * groups. This way the user may see visual interruptions when the display mode changes.
+ */
+
+ boolean allowGroupSwitching;
+
+ /**
+ * The primary physical and render refresh rate ranges represent DisplayManager's general
+ * guidance on the display modes SurfaceFlinger will consider when switching refresh
+ * rates and scheduling the frame rate. Unless SurfaceFlinger has a specific reason to do
+ * otherwise, it will stay within this range.
+ */
+ RefreshRateRanges primaryRanges;
+
+ /**
+ * The app request physical and render refresh rate ranges allow SurfaceFlinger to consider
+ * more display modes when switching refresh rates. Although SurfaceFlinger will
+ * generally stay within the primary range, specific considerations, such as layer frame
+ * rate settings specified via the setFrameRate() API, may cause SurfaceFlinger to go
+ * outside the primary range. SurfaceFlinger never goes outside the app request range.
+ * The app request range will be greater than or equal to the primary refresh rate range,
+ * never smaller.
+ */
+ RefreshRateRanges appRequestRanges;
+}
diff --git a/libs/gui/aidl/android/gui/DisplayPrimaries.aidl b/libs/gui/aidl/android/gui/DisplayPrimaries.aidl
new file mode 100644
index 0000000000..dbf668c629
--- /dev/null
+++ b/libs/gui/aidl/android/gui/DisplayPrimaries.aidl
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.gui;
+
+// copied from libui ConfigStoreTypes.h
+
+/** @hide */
+parcelable DisplayPrimaries {
+ parcelable CieXyz {
+ float X;
+ float Y;
+ float Z;
+ }
+
+ CieXyz red;
+ CieXyz green;
+ CieXyz blue;
+ CieXyz white;
+}
diff --git a/libs/gui/aidl/android/gui/DisplayedFrameStats.aidl b/libs/gui/aidl/android/gui/DisplayedFrameStats.aidl
new file mode 100644
index 0000000000..f4b6dadc49
--- /dev/null
+++ b/libs/gui/aidl/android/gui/DisplayedFrameStats.aidl
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.gui;
+
+/** @hide */
+parcelable DisplayedFrameStats {
+ /* The number of frames represented by this sample. */
+ long numFrames = 0;
+
+ /* A histogram counting how many times a pixel of a given value was displayed onscreen for
+ * FORMAT_COMPONENT_0. The buckets of the histogram are evenly weighted, the number of buckets
+ * is device specific. eg, for RGBA_8888, if sampleComponent0 is {10, 6, 4, 1} this means that
+ * 10 red pixels were displayed onscreen in range 0x00->0x3F, 6 red pixels
+ * were displayed onscreen in range 0x40->0x7F, etc.
+ */
+ long[] component_0_sample;
+
+ /* The same sample definition as sampleComponent0, but for FORMAT_COMPONENT_1. */
+ long[] component_1_sample;
+
+ /* The same sample definition as sampleComponent0, but for FORMAT_COMPONENT_2. */
+ long[] component_2_sample;
+
+ /* The same sample definition as sampleComponent0, but for FORMAT_COMPONENT_3. */
+ long[] component_3_sample;
+}
diff --git a/libs/gui/aidl/android/gui/DynamicDisplayInfo.aidl b/libs/gui/aidl/android/gui/DynamicDisplayInfo.aidl
new file mode 100644
index 0000000000..3114929e86
--- /dev/null
+++ b/libs/gui/aidl/android/gui/DynamicDisplayInfo.aidl
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.gui;
+
+import android.gui.DisplayMode;
+import android.gui.HdrCapabilities;
+
+// Information about a physical display which may change on hotplug reconnect.
+// Make sure to sync with libui DynamicDisplayInfo.h
+
+/** @hide */
+parcelable DynamicDisplayInfo {
+ List<DisplayMode> supportedDisplayModes;
+
+ int activeDisplayModeId;
+ float renderFrameRate;
+
+ int[] supportedColorModes;
+ int activeColorMode;
+ HdrCapabilities hdrCapabilities;
+
+ // True if the display reports support for HDMI 2.1 Auto Low Latency Mode.
+ // For more information, see the HDMI 2.1 specification.
+ boolean autoLowLatencyModeSupported;
+
+ // True if the display reports support for Game Content Type.
+ // For more information, see the HDMI 1.4 specification.
+ boolean gameContentTypeSupported;
+
+ // The boot display mode preferred by the implementation.
+ int preferredBootDisplayMode;
+}
diff --git a/libs/gui/aidl/android/gui/FrameEvent.aidl b/libs/gui/aidl/android/gui/FrameEvent.aidl
new file mode 100644
index 0000000000..aaabdb5b54
--- /dev/null
+++ b/libs/gui/aidl/android/gui/FrameEvent.aidl
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.gui;
+
+// Identifiers for all the events that may be recorded or reported.
+
+/** @hide */
+@Backing(type="int")
+enum FrameEvent {
+ POSTED = 0,
+ REQUESTED_PRESENT = 1,
+ LATCH = 2,
+ ACQUIRE = 3,
+ FIRST_REFRESH_START = 4,
+ LAST_REFRESH_START = 5,
+ GPU_COMPOSITION_DONE = 6,
+ DISPLAY_PRESENT = 7,
+ DEQUEUE_READY = 8,
+ RELEASE = 9,
+ EVENT_COUNT = 10 // Not an actual event.
+}
diff --git a/libs/gui/aidl/android/gui/FrameStats.aidl b/libs/gui/aidl/android/gui/FrameStats.aidl
new file mode 100644
index 0000000000..a145e74b11
--- /dev/null
+++ b/libs/gui/aidl/android/gui/FrameStats.aidl
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.gui;
+
+// Make sure to sync with libui FrameStats.h
+
+/** @hide */
+parcelable FrameStats {
+ /*
+ * Approximate refresh time, in nanoseconds.
+ */
+ long refreshPeriodNano;
+
+ /*
+ * The times in nanoseconds for when the frame contents were posted by the producer (e.g.
+ * the application). They are either explicitly set or defaulted to the time when
+ * Surface::queueBuffer() was called.
+ */
+ long[] desiredPresentTimesNano;
+
+ /*
+ * The times in milliseconds for when the frame contents were presented on the screen.
+ */
+ long[] actualPresentTimesNano;
+
+ /*
+ * The times in nanoseconds for when the frame contents were ready to be presented. Note that
+ * a frame can be posted and still it contents being rendered asynchronously in GL. In such a
+ * case these are the times when the frame contents were completely rendered (i.e. their fences
+ * signaled).
+ */
+ long[] frameReadyTimesNano;
+}
diff --git a/libs/gui/include/gui/FrameTimelineInfo.h b/libs/gui/aidl/android/gui/FrameTimelineInfo.aidl
index 255ce568d2..6a86c6a5cd 100644
--- a/libs/gui/include/gui/FrameTimelineInfo.h
+++ b/libs/gui/aidl/android/gui/FrameTimelineInfo.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright 2021 The Android Open Source Project
+ * Copyright 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,36 +14,27 @@
* limitations under the License.
*/
-#pragma once
+package android.gui;
-#include <stdint.h>
-
-#include <binder/Parcel.h>
-
-namespace android {
-
-struct FrameTimelineInfo {
+/** @hide */
+parcelable FrameTimelineInfo {
// Needs to be in sync with android.graphics.FrameInfo.INVALID_VSYNC_ID in java
- static constexpr int64_t INVALID_VSYNC_ID = -1;
+ const long INVALID_VSYNC_ID = -1;
// The vsync id that was used to start the transaction
- int64_t vsyncId = INVALID_VSYNC_ID;
+ long vsyncId = INVALID_VSYNC_ID;
// The id of the input event that caused this buffer
// Default is android::os::IInputConstants::INVALID_INPUT_EVENT_ID = 0
// We copy the value of the input event ID instead of including the header, because libgui
// header libraries containing FrameTimelineInfo must be available to vendors, but libinput is
// not directly vendor available.
- int32_t inputEventId = 0;
+ int inputEventId = 0;
// The current time in nanoseconds the application started to render the frame.
- int64_t startTimeNanos = 0;
-
- status_t write(Parcel& output) const;
- status_t read(const Parcel& input);
-
- void merge(const FrameTimelineInfo& other);
- void clear();
-};
+ long startTimeNanos = 0;
-} // namespace android
+ // Whether this vsyncId should be used to heuristically select the display refresh rate
+ // TODO(b/281695725): Clean this up once TextureView use setFrameRate API
+ boolean useForRefreshRateSelection = false;
+}
diff --git a/libs/gui/aidl/android/gui/HdrCapabilities.aidl b/libs/gui/aidl/android/gui/HdrCapabilities.aidl
new file mode 100644
index 0000000000..9d06da9f27
--- /dev/null
+++ b/libs/gui/aidl/android/gui/HdrCapabilities.aidl
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.gui;
+
+// Make sure to sync with libui HdrCapabilities.h
+
+/** @hide */
+parcelable HdrCapabilities {
+ int[] supportedHdrTypes;
+ float maxLuminance;
+ float maxAverageLuminance;
+ float minLuminance;
+}
diff --git a/libs/gui/aidl/android/gui/HdrConversionCapability.aidl b/libs/gui/aidl/android/gui/HdrConversionCapability.aidl
new file mode 100644
index 0000000000..1bcfd38eff
--- /dev/null
+++ b/libs/gui/aidl/android/gui/HdrConversionCapability.aidl
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.gui;
+
+// TODO(b/265277221): use android.hardware.graphics.common.HdrConversionCapability.aidl
+/** @hide */
+parcelable HdrConversionCapability {
+ int sourceType;
+ int outputType;
+ boolean addsLatency;
+} \ No newline at end of file
diff --git a/libs/gui/aidl/android/gui/HdrConversionStrategy.aidl b/libs/gui/aidl/android/gui/HdrConversionStrategy.aidl
new file mode 100644
index 0000000000..1be74b46e7
--- /dev/null
+++ b/libs/gui/aidl/android/gui/HdrConversionStrategy.aidl
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.gui;
+
+// TODO(b/265277221): use android.hardware.graphics.common.HdrConversionStrategy.aidl
+/** @hide */
+union HdrConversionStrategy {
+ boolean passthrough = true;
+ int[] autoAllowedHdrTypes;
+ int forceHdrConversion;
+}
diff --git a/libs/gui/aidl/android/gui/IHdrConversionConstants.aidl b/libs/gui/aidl/android/gui/IHdrConversionConstants.aidl
new file mode 100644
index 0000000000..7697f2995b
--- /dev/null
+++ b/libs/gui/aidl/android/gui/IHdrConversionConstants.aidl
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.gui;
+
+/** @hide */
+interface IHdrConversionConstants
+{
+ /** HDR Conversion Mode when there is no conversion being done */
+ const int HdrConversionModePassthrough = 1;
+
+ /** HDR Conversion Mode when HDR conversion is decided by the system or implementation */
+ const int HdrConversionModeAuto = 2;
+
+ /** HDR Conversion Mode when the output HDR types is selected by the user or framework */
+ const int HdrConversionModeForce = 3;
+} \ No newline at end of file
diff --git a/libs/gui/aidl/android/gui/IHdrLayerInfoListener.aidl b/libs/gui/aidl/android/gui/IHdrLayerInfoListener.aidl
index fc809c4c88..e8c36ee001 100644
--- a/libs/gui/aidl/android/gui/IHdrLayerInfoListener.aidl
+++ b/libs/gui/aidl/android/gui/IHdrLayerInfoListener.aidl
@@ -19,7 +19,9 @@ package android.gui;
/** @hide */
oneway interface IHdrLayerInfoListener {
// Callback with the total number of HDR layers, the dimensions of the largest layer,
- // and a placeholder flags
+ // a placeholder flags, and the max desired HDR/SDR ratio. The max desired HDR/SDR
+ // ratio may be positive infinity to indicate an unbounded ratio.
// TODO (b/182312559): Define the flags (likely need an indicator that a UDFPS layer is present)
- void onHdrLayerInfoChanged(int numberOfHdrLayers, int maxW, int maxH, int flags);
+ void onHdrLayerInfoChanged(int numberOfHdrLayers, int maxW, int maxH,
+ int flags, float maxDesiredHdrSdrRatio);
} \ No newline at end of file
diff --git a/libs/gui/aidl/android/gui/ISurfaceComposer.aidl b/libs/gui/aidl/android/gui/ISurfaceComposer.aidl
index b31b37bada..539a1c140e 100644
--- a/libs/gui/aidl/android/gui/ISurfaceComposer.aidl
+++ b/libs/gui/aidl/android/gui/ISurfaceComposer.aidl
@@ -16,39 +16,117 @@
package android.gui;
-import android.gui.DisplayCaptureArgs;
+import android.gui.Color;
+import android.gui.CompositionPreference;
+import android.gui.ContentSamplingAttributes;
import android.gui.DisplayBrightness;
+import android.gui.DisplayCaptureArgs;
+import android.gui.DisplayDecorationSupport;
+import android.gui.DisplayedFrameStats;
+import android.gui.DisplayModeSpecs;
+import android.gui.DisplayPrimaries;
import android.gui.DisplayState;
import android.gui.DisplayStatInfo;
+import android.gui.DynamicDisplayInfo;
+import android.gui.FrameEvent;
+import android.gui.FrameStats;
+import android.gui.HdrConversionCapability;
+import android.gui.HdrConversionStrategy;
+import android.gui.IDisplayEventConnection;
+import android.gui.IFpsListener;
import android.gui.IHdrLayerInfoListener;
-import android.gui.LayerCaptureArgs;
+import android.gui.IRegionSamplingListener;
import android.gui.IScreenCaptureListener;
+import android.gui.ISurfaceComposerClient;
+import android.gui.ITunnelModeEnabledListener;
+import android.gui.IWindowInfosListener;
+import android.gui.IWindowInfosPublisher;
+import android.gui.LayerCaptureArgs;
+import android.gui.LayerDebugInfo;
+import android.gui.OverlayProperties;
+import android.gui.PullAtomData;
+import android.gui.ARect;
+import android.gui.StaticDisplayInfo;
+import android.gui.WindowInfosListenerInfo;
/** @hide */
interface ISurfaceComposer {
- /* create a virtual display
+ enum VsyncSource {
+ eVsyncSourceApp = 0,
+ eVsyncSourceSurfaceFlinger = 1
+ }
+
+ enum EventRegistration {
+ modeChanged = 1 << 0,
+ frameRateOverride = 1 << 1,
+ }
+
+ /**
+ * Signal that we're done booting.
+ * Requires ACCESS_SURFACE_FLINGER permission
+ */
+ void bootFinished();
+
+ /**
+ * Create a display event connection
+ *
+ * layerHandle
+ * Optional binder handle representing a Layer in SF to associate the new
+ * DisplayEventConnection with. This handle can be found inside a surface control after
+ * surface creation, see ISurfaceComposerClient::createSurface. Set to null if no layer
+ * association should be made.
+ */
+ @nullable IDisplayEventConnection createDisplayEventConnection(VsyncSource vsyncSource,
+ EventRegistration eventRegistration, @nullable IBinder layerHandle);
+
+ /**
+ * Create a connection with SurfaceFlinger.
+ */
+ @nullable ISurfaceComposerClient createConnection();
+
+ /**
+ * Create a virtual display
+ *
+ * displayName
+ * The name of the virtual display
+ * secure
+ * Whether this virtual display is secure
+ * requestedRefreshRate
+ * The refresh rate, frames per second, to request on the virtual display.
+ * This is just a request, the actual rate may be adjusted to align well
+ * with physical displays running concurrently. If 0 is specified, the
+ * virtual display is refreshed at the physical display refresh rate.
+ *
* requires ACCESS_SURFACE_FLINGER permission.
*/
- @nullable IBinder createDisplay(@utf8InCpp String displayName, boolean secure);
+ @nullable IBinder createDisplay(@utf8InCpp String displayName, boolean secure,
+ float requestedRefreshRate);
- /* destroy a virtual display
+ /**
+ * Destroy a virtual display
* requires ACCESS_SURFACE_FLINGER permission.
*/
void destroyDisplay(IBinder display);
- /* get stable IDs for connected physical displays.
+ /**
+ * Get stable IDs for connected physical displays.
*/
long[] getPhysicalDisplayIds();
- long getPrimaryPhysicalDisplayId();
-
- /* get token for a physical display given its stable ID obtained via getPhysicalDisplayIds or a
- * DisplayEventReceiver hotplug event.
+ /**
+ * Get token for a physical display given its stable ID obtained via getPhysicalDisplayIds or
+ * a DisplayEventReceiver hotplug event.
*/
@nullable IBinder getPhysicalDisplayToken(long displayId);
- /* set display power mode. depending on the mode, it can either trigger
+ /**
+ * Returns the frame timestamps supported by SurfaceFlinger.
+ */
+ FrameEvent[] getSupportedFrameTimestamps();
+
+ /**
+ * Set display power mode. depending on the mode, it can either trigger
* screen on, off or low power mode and wait for it to complete.
* requires ACCESS_SURFACE_FLINGER permission.
*/
@@ -60,12 +138,33 @@ interface ISurfaceComposer {
* video frames */
DisplayStatInfo getDisplayStats(@nullable IBinder display);
- /**
+ /**
* Get transactional state of given display.
*/
DisplayState getDisplayState(IBinder display);
/**
+ * Gets immutable information about given physical display.
+ */
+ StaticDisplayInfo getStaticDisplayInfo(long displayId);
+
+ /**
+ * Gets dynamic information about given physical display.
+ */
+ DynamicDisplayInfo getDynamicDisplayInfoFromId(long displayId);
+
+ DynamicDisplayInfo getDynamicDisplayInfoFromToken(IBinder display);
+
+ DisplayPrimaries getDisplayNativePrimaries(IBinder display);
+
+ void setActiveColorMode(IBinder display, int colorMode);
+
+ /**
+ * Sets the user-preferred display mode that a device should boot in.
+ */
+ void setBootDisplayMode(IBinder display, int displayModeId);
+
+ /**
* Clears the user-preferred display mode. The device should now boot in system preferred
* display mode.
*/
@@ -85,6 +184,28 @@ interface ISurfaceComposer {
boolean getBootDisplayModeSupport();
/**
+ * Gets the HDR conversion capabilities of the device. The conversion capability defines whether
+ * conversion from sourceType to outputType is possible (with or without latency).
+ *
+ * Requires the ACCESS_SURFACE_FLINGER permission.
+ */
+ List<HdrConversionCapability> getHdrConversionCapabilities();
+
+ /**
+ * Sets the HDR conversion strategy of the device.
+ * Returns the preferred HDR output type of the device, in case when HdrConversionStrategy has
+ * autoAllowedHdrTypes set. Returns Hdr::INVALID in other cases.
+ *
+ * Requires the ACCESS_SURFACE_FLINGER permission.
+ */
+ int setHdrConversionStrategy(in HdrConversionStrategy hdrConversionStrategy);
+
+ /**
+ * Gets whether HDR output conversion operations are supported on the device.
+ */
+ boolean getHdrOutputConversionSupport();
+
+ /**
* Switches Auto Low Latency Mode on/off on the connected display, if it is
* available. This should only be called if the display supports Auto Low
* Latency Mode as reported in #getDynamicDisplayInfo.
@@ -110,7 +231,13 @@ interface ISurfaceComposer {
* match the size of the output buffer.
*/
void captureDisplay(in DisplayCaptureArgs args, IScreenCaptureListener listener);
+
+ /**
+ * Capture the specified screen. This requires the READ_FRAME_BUFFER
+ * permission.
+ */
void captureDisplayById(long displayId, IScreenCaptureListener listener);
+
/**
* Capture a subtree of the layer hierarchy, potentially ignoring the root node.
* This requires READ_FRAME_BUFFER permission. This function will fail if there
@@ -118,13 +245,143 @@ interface ISurfaceComposer {
*/
void captureLayers(in LayerCaptureArgs args, IScreenCaptureListener listener);
- /*
+ /**
+ * Clears the frame statistics for animations.
+ *
+ * Requires the ACCESS_SURFACE_FLINGER permission.
+ */
+ void clearAnimationFrameStats();
+
+ /**
+ * Gets the frame statistics for animations.
+ *
+ * Requires the ACCESS_SURFACE_FLINGER permission.
+ */
+ FrameStats getAnimationFrameStats();
+
+ /**
+ * Overrides the supported HDR modes for the given display device.
+ *
+ * Requires the ACCESS_SURFACE_FLINGER permission.
+ */
+ void overrideHdrTypes(IBinder display, in int[] hdrTypes);
+
+ /**
+ * Pulls surfaceflinger atoms global stats and layer stats to pipe to statsd.
+ *
+ * Requires the calling uid be from system server.
+ */
+ PullAtomData onPullAtom(int atomId);
+
+ /**
+ * Gets the list of active layers in Z order for debugging purposes
+ *
+ * Requires the ACCESS_SURFACE_FLINGER permission.
+ */
+ List<LayerDebugInfo> getLayerDebugInfo();
+
+ boolean getColorManagement();
+
+ /**
+ * Gets the composition preference of the default data space and default pixel format,
+ * as well as the wide color gamut data space and wide color gamut pixel format.
+ * If the wide color gamut data space is V0_SRGB, then it implies that the platform
+ * has no wide color gamut support.
+ *
+ */
+ CompositionPreference getCompositionPreference();
+
+ /**
+ * Requires the ACCESS_SURFACE_FLINGER permission.
+ */
+ ContentSamplingAttributes getDisplayedContentSamplingAttributes(IBinder display);
+
+ /**
+ * Turns on the color sampling engine on the display.
+ *
+ * Requires the ACCESS_SURFACE_FLINGER permission.
+ */
+ void setDisplayContentSamplingEnabled(IBinder display, boolean enable, byte componentMask, long maxFrames);
+
+ /**
+ * Returns statistics on the color profile of the last frame displayed for a given display
+ *
+ * Requires the ACCESS_SURFACE_FLINGER permission.
+ */
+ DisplayedFrameStats getDisplayedContentSample(IBinder display, long maxFrames, long timestamp);
+
+ /**
+ * Gets whether SurfaceFlinger can support protected content in GPU composition.
+ */
+ boolean getProtectedContentSupport();
+
+ /**
* Queries whether the given display is a wide color display.
* Requires the ACCESS_SURFACE_FLINGER permission.
*/
boolean isWideColorDisplay(IBinder token);
- /*
+ /**
+ * Registers a listener to stream median luma updates from SurfaceFlinger.
+ *
+ * The sampling area is bounded by both samplingArea and the given stopLayerHandle
+ * (i.e., only layers behind the stop layer will be captured and sampled).
+ *
+ * Multiple listeners may be provided so long as they have independent listeners.
+ * If multiple listeners are provided, the effective sampling region for each listener will
+ * be bounded by whichever stop layer has a lower Z value.
+ *
+ * Requires the same permissions as captureLayers and captureScreen.
+ */
+ void addRegionSamplingListener(in ARect samplingArea, @nullable IBinder stopLayerHandle, IRegionSamplingListener listener);
+
+ /**
+ * Removes a listener that was streaming median luma updates from SurfaceFlinger.
+ */
+ void removeRegionSamplingListener(IRegionSamplingListener listener);
+
+ /**
+ * Registers a listener that streams fps updates from SurfaceFlinger.
+ *
+ * The listener will stream fps updates for the layer tree rooted at the layer denoted by the
+ * task ID, i.e., the layer must have the task ID as part of its layer metadata with key
+ * METADATA_TASK_ID. If there is no such layer, then no fps is expected to be reported.
+ *
+ * Multiple listeners may be supported.
+ *
+ * Requires the READ_FRAME_BUFFER permission.
+ */
+ void addFpsListener(int taskId, IFpsListener listener);
+
+ /**
+ * Removes a listener that was streaming fps updates from SurfaceFlinger.
+ */
+ void removeFpsListener(IFpsListener listener);
+
+ /**
+ * Registers a listener to receive tunnel mode enabled updates from SurfaceFlinger.
+ *
+ * Requires ACCESS_SURFACE_FLINGER permission.
+ */
+ void addTunnelModeEnabledListener(ITunnelModeEnabledListener listener);
+
+ /**
+ * Removes a listener that was receiving tunnel mode enabled updates from SurfaceFlinger.
+ *
+ * Requires ACCESS_SURFACE_FLINGER permission.
+ */
+ void removeTunnelModeEnabledListener(ITunnelModeEnabledListener listener);
+
+ /**
+ * Sets the refresh rate boundaries for the display.
+ *
+ * @see DisplayModeSpecs.aidl for details.
+ */
+ void setDesiredDisplayModeSpecs(IBinder displayToken, in DisplayModeSpecs specs);
+
+ DisplayModeSpecs getDesiredDisplayModeSpecs(IBinder displayToken);
+
+ /**
* Gets whether brightness operations are supported on a display.
*
* displayToken
@@ -138,7 +395,7 @@ interface ISurfaceComposer {
*/
boolean getDisplayBrightnessSupport(IBinder displayToken);
- /*
+ /**
* Sets the brightness of a display.
*
* displayToken
@@ -153,7 +410,7 @@ interface ISurfaceComposer {
*/
void setDisplayBrightness(IBinder displayToken, in DisplayBrightness brightness);
- /*
+ /**
* Adds a listener that receives HDR layer information. This is used in combination
* with setDisplayBrightness to adjust the display brightness depending on factors such
* as whether or not HDR is in use.
@@ -162,7 +419,7 @@ interface ISurfaceComposer {
*/
void addHdrLayerInfoListener(IBinder displayToken, IHdrLayerInfoListener listener);
- /*
+ /**
* Removes a listener that was added with addHdrLayerInfoListener.
*
* Returns NO_ERROR upon success, NAME_NOT_FOUND if the display is invalid, and BAD_VALUE if
@@ -171,7 +428,7 @@ interface ISurfaceComposer {
*/
void removeHdrLayerInfoListener(IBinder displayToken, IHdrLayerInfoListener listener);
- /*
+ /**
* Sends a power boost to the composer. This function is asynchronous.
*
* boostId
@@ -179,5 +436,75 @@ interface ISurfaceComposer {
*
* Returns NO_ERROR upon success.
*/
- void notifyPowerBoost(int boostId);
+ oneway void notifyPowerBoost(int boostId);
+
+ /*
+ * Sets the global configuration for all the shadows drawn by SurfaceFlinger. Shadow follows
+ * material design guidelines.
+ *
+ * ambientColor
+ * Color to the ambient shadow. The alpha is premultiplied.
+ *
+ * spotColor
+ * Color to the spot shadow. The alpha is premultiplied. The position of the spot shadow
+ * depends on the light position.
+ *
+ * lightPosY/lightPosZ
+ * Position of the light used to cast the spot shadow. The X value is always the display
+ * width / 2.
+ *
+ * lightRadius
+ * Radius of the light casting the shadow.
+ */
+ oneway void setGlobalShadowSettings(in Color ambientColor, in Color spotColor, float lightPosY, float lightPosZ, float lightRadius);
+
+ /**
+ * Gets whether a display supports DISPLAY_DECORATION layers.
+ *
+ * displayToken
+ * The token of the display.
+ * outSupport
+ * An output parameter for whether/how the display supports
+ * DISPLAY_DECORATION layers.
+ *
+ * Returns NO_ERROR upon success. Otherwise,
+ * NAME_NOT_FOUND if the display is invalid, or
+ * BAD_VALUE if the output parameter is invalid.
+ */
+ @nullable DisplayDecorationSupport getDisplayDecorationSupport(IBinder displayToken);
+
+ /**
+ * Set the override frame rate for a specified uid by GameManagerService.
+ * Passing the frame rate and uid to SurfaceFlinger to update the override mapping
+ * in the scheduler.
+ */
+ void setOverrideFrameRate(int uid, float frameRate);
+
+ /**
+ * Gets priority of the RenderEngine in SurfaceFlinger.
+ */
+ int getGpuContextPriority();
+
+ /**
+ * Gets the number of buffers SurfaceFlinger would need acquire. This number
+ * would be propagated to the client via MIN_UNDEQUEUED_BUFFERS so that the
+ * client could allocate enough buffers to match SF expectations of the
+ * pipeline depth. SurfaceFlinger will make sure that it will give the app at
+ * least the time configured as the 'appDuration' before trying to latch
+ * the buffer.
+ *
+ * The total buffers needed for a given configuration is basically the
+ * numbers of vsyncs a single buffer is used across the stack. For the default
+ * configuration a buffer is held ~1 vsync by the app, ~1 vsync by SurfaceFlinger
+ * and 1 vsync by the display. The extra buffers are calculated as the
+ * number of additional buffers on top of the 2 buffers already present
+ * in MIN_UNDEQUEUED_BUFFERS.
+ */
+ int getMaxAcquiredBufferCount();
+
+ WindowInfosListenerInfo addWindowInfosListener(IWindowInfosListener windowInfosListener);
+
+ void removeWindowInfosListener(IWindowInfosListener windowInfosListener);
+
+ OverlayProperties getOverlaySupport();
}
diff --git a/libs/gui/aidl/android/gui/ISurfaceComposerClient.aidl b/libs/gui/aidl/android/gui/ISurfaceComposerClient.aidl
new file mode 100644
index 0000000000..68781ce953
--- /dev/null
+++ b/libs/gui/aidl/android/gui/ISurfaceComposerClient.aidl
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.gui;
+
+import android.gui.CreateSurfaceResult;
+import android.gui.FrameStats;
+import android.gui.LayerMetadata;
+
+/** @hide */
+interface ISurfaceComposerClient {
+
+ // flags for createSurface()
+ // (keep in sync with SurfaceControl.java)
+ const int eHidden = 0x00000004;
+ const int eDestroyBackbuffer = 0x00000020;
+ const int eSkipScreenshot = 0x00000040;
+ const int eSecure = 0x00000080;
+ const int eNonPremultiplied = 0x00000100;
+ const int eOpaque = 0x00000400;
+ const int eProtectedByApp = 0x00000800;
+ const int eProtectedByDRM = 0x00001000;
+ const int eCursorWindow = 0x00002000;
+ const int eNoColorFill = 0x00004000;
+
+ const int eFXSurfaceBufferQueue = 0x00000000;
+ const int eFXSurfaceEffect = 0x00020000;
+ const int eFXSurfaceBufferState = 0x00040000;
+ const int eFXSurfaceContainer = 0x00080000;
+ const int eFXSurfaceMask = 0x000F0000;
+
+ /**
+ * Requires ACCESS_SURFACE_FLINGER permission
+ */
+ CreateSurfaceResult createSurface(@utf8InCpp String name, int flags, @nullable IBinder parent, in LayerMetadata metadata);
+
+ /**
+ * Requires ACCESS_SURFACE_FLINGER permission
+ */
+ void clearLayerFrameStats(IBinder handle);
+
+ /**
+ * Requires ACCESS_SURFACE_FLINGER permission
+ */
+ FrameStats getLayerFrameStats(IBinder handle);
+
+ CreateSurfaceResult mirrorSurface(IBinder mirrorFromHandle);
+
+ CreateSurfaceResult mirrorDisplay(long displayId);
+}
diff --git a/libs/gui/aidl/android/gui/ITransactionTraceListener.aidl b/libs/gui/aidl/android/gui/ITransactionTraceListener.aidl
deleted file mode 100644
index 5cd12fdc2b..0000000000
--- a/libs/gui/aidl/android/gui/ITransactionTraceListener.aidl
+++ /dev/null
@@ -1,6 +0,0 @@
-package android.gui;
-
-/** @hide */
-interface ITransactionTraceListener {
- void onToggled(boolean enabled);
-} \ No newline at end of file
diff --git a/libs/gui/aidl/android/gui/LayerDebugInfo.aidl b/libs/gui/aidl/android/gui/LayerDebugInfo.aidl
new file mode 100644
index 0000000000..faca980f3c
--- /dev/null
+++ b/libs/gui/aidl/android/gui/LayerDebugInfo.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.gui;
+
+parcelable LayerDebugInfo cpp_header "gui/LayerDebugInfo.h";
diff --git a/libs/gui/aidl/android/gui/LayerMetadata.aidl b/libs/gui/aidl/android/gui/LayerMetadata.aidl
new file mode 100644
index 0000000000..1368ac512f
--- /dev/null
+++ b/libs/gui/aidl/android/gui/LayerMetadata.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.gui;
+
+parcelable LayerMetadata cpp_header "gui/LayerMetadata.h";
diff --git a/libs/gui/aidl/android/gui/OverlayProperties.aidl b/libs/gui/aidl/android/gui/OverlayProperties.aidl
new file mode 100644
index 0000000000..5fb1a83c65
--- /dev/null
+++ b/libs/gui/aidl/android/gui/OverlayProperties.aidl
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.gui;
+
+/** @hide */
+parcelable OverlayProperties {
+ parcelable SupportedBufferCombinations {
+ int[] pixelFormats;
+ int[] standards;
+ int[] transfers;
+ int[] ranges;
+ }
+ SupportedBufferCombinations[] combinations;
+
+ boolean supportMixedColorSpaces;
+}
diff --git a/libs/gui/aidl/android/gui/PullAtomData.aidl b/libs/gui/aidl/android/gui/PullAtomData.aidl
new file mode 100644
index 0000000000..c307cef70e
--- /dev/null
+++ b/libs/gui/aidl/android/gui/PullAtomData.aidl
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.gui;
+
+/** @hide */
+parcelable PullAtomData {
+ byte[] data;
+ boolean success;
+}
diff --git a/libs/gui/aidl/android/gui/StaticDisplayInfo.aidl b/libs/gui/aidl/android/gui/StaticDisplayInfo.aidl
new file mode 100644
index 0000000000..0ccda56ef5
--- /dev/null
+++ b/libs/gui/aidl/android/gui/StaticDisplayInfo.aidl
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.gui;
+
+import android.gui.DisplayConnectionType;
+import android.gui.DeviceProductInfo;
+import android.gui.Rotation;
+
+/** @hide */
+parcelable StaticDisplayInfo {
+ DisplayConnectionType connectionType = DisplayConnectionType.Internal;
+ float density;
+ boolean secure;
+ @nullable DeviceProductInfo deviceProductInfo;
+ Rotation installOrientation = Rotation.Rotation0;
+}
diff --git a/libs/gui/aidl/android/gui/TrustedPresentationThresholds.aidl b/libs/gui/aidl/android/gui/TrustedPresentationThresholds.aidl
new file mode 100644
index 0000000000..1eea5b44a4
--- /dev/null
+++ b/libs/gui/aidl/android/gui/TrustedPresentationThresholds.aidl
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.gui;
+
+parcelable TrustedPresentationThresholds {
+ float minAlpha = -1.0f;
+ float minFractionRendered = -1.0f;
+
+ int stabilityRequirementMs = 0;
+}
diff --git a/libs/gui/aidl/android/gui/WindowInfosListenerInfo.aidl b/libs/gui/aidl/android/gui/WindowInfosListenerInfo.aidl
new file mode 100644
index 0000000000..0ca13b768a
--- /dev/null
+++ b/libs/gui/aidl/android/gui/WindowInfosListenerInfo.aidl
@@ -0,0 +1,25 @@
+/**
+ * Copyright (c) 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.gui;
+
+import android.gui.IWindowInfosPublisher;
+
+/** @hide */
+parcelable WindowInfosListenerInfo {
+ long listenerId;
+ IWindowInfosPublisher windowInfosPublisher;
+} \ No newline at end of file
diff --git a/libs/gui/android/gui/FocusRequest.aidl b/libs/gui/android/gui/FocusRequest.aidl
index b13c60049c..62d1b68147 100644
--- a/libs/gui/android/gui/FocusRequest.aidl
+++ b/libs/gui/android/gui/FocusRequest.aidl
@@ -24,15 +24,6 @@ parcelable FocusRequest {
@nullable IBinder token;
@utf8InCpp String windowName;
/**
- * The token that the caller expects currently to be focused. If the
- * specified token does not match the currently focused window, this request will be dropped.
- * If the specified focused token matches the currently focused window, the call will succeed.
- * Set this to "null" if this call should succeed no matter what the currently focused token
- * is.
- */
- @nullable IBinder focusedToken;
- @utf8InCpp String focusedWindowName;
- /**
* SYSTEM_TIME_MONOTONIC timestamp in nanos set by the client (wm) when requesting the focus
* change. This determines which request gets precedence if there is a focus change request
* from another source such as pointer down.
diff --git a/libs/gui/android/gui/IWindowInfosListener.aidl b/libs/gui/android/gui/IWindowInfosListener.aidl
index a5b2762318..07cb5ed0e6 100644
--- a/libs/gui/android/gui/IWindowInfosListener.aidl
+++ b/libs/gui/android/gui/IWindowInfosListener.aidl
@@ -16,12 +16,9 @@
package android.gui;
-import android.gui.DisplayInfo;
-import android.gui.IWindowInfosReportedListener;
-import android.gui.WindowInfo;
+import android.gui.WindowInfosUpdate;
/** @hide */
-oneway interface IWindowInfosListener
-{
- void onWindowInfosChanged(in WindowInfo[] windowInfos, in DisplayInfo[] displayInfos, in @nullable IWindowInfosReportedListener windowInfosReportedListener);
+oneway interface IWindowInfosListener {
+ void onWindowInfosChanged(in WindowInfosUpdate update);
}
diff --git a/libs/gui/android/gui/IWindowInfosPublisher.aidl b/libs/gui/android/gui/IWindowInfosPublisher.aidl
new file mode 100644
index 0000000000..5a9c32845e
--- /dev/null
+++ b/libs/gui/android/gui/IWindowInfosPublisher.aidl
@@ -0,0 +1,23 @@
+/**
+ * Copyright (c) 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.gui;
+
+/** @hide */
+oneway interface IWindowInfosPublisher
+{
+ void ackWindowInfosReceived(long vsyncId, long listenerId);
+}
diff --git a/libs/gui/android/gui/WindowInfosUpdate.aidl b/libs/gui/android/gui/WindowInfosUpdate.aidl
new file mode 100644
index 0000000000..0c6109da8f
--- /dev/null
+++ b/libs/gui/android/gui/WindowInfosUpdate.aidl
@@ -0,0 +1,22 @@
+/*
+** Copyright 2023, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+package android.gui;
+
+import android.gui.DisplayInfo;
+import android.gui.WindowInfo;
+
+parcelable WindowInfosUpdate cpp_header "gui/WindowInfosUpdate.h";
diff --git a/libs/gui/fuzzer/Android.bp b/libs/gui/fuzzer/Android.bp
new file mode 100644
index 0000000000..82e1b5ae4d
--- /dev/null
+++ b/libs/gui/fuzzer/Android.bp
@@ -0,0 +1,136 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "frameworks_native_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ default_applicable_licenses: ["frameworks_native_license"],
+}
+
+cc_defaults {
+ name: "libgui_fuzzer_defaults",
+ static_libs: [
+ "android.hidl.token@1.0-utils",
+ "libbinder_random_parcel",
+ "libgui_aidl_static",
+ "libgui_window_info_static",
+ "libpdx",
+ "libgmock",
+ "libgui_mocks",
+ "libgmock_ndk",
+ "libgmock_main",
+ "libgtest_ndk_c++",
+ "libgmock_main_ndk",
+ "librenderengine_mocks",
+ "perfetto_trace_protos",
+ "libcompositionengine_mocks",
+ "perfetto_trace_protos",
+ ],
+ shared_libs: [
+ "android.hardware.configstore@1.0",
+ "android.hardware.configstore-utils",
+ "android.hardware.graphics.bufferqueue@1.0",
+ "android.hardware.graphics.bufferqueue@2.0",
+ "android.hardware.power-V4-cpp",
+ "android.hidl.token@1.0",
+ "libSurfaceFlingerProp",
+ "libgui",
+ "libbase",
+ "liblog",
+ "libEGL",
+ "libGLESv2",
+ "libbinder",
+ "libcutils",
+ "libhidlbase",
+ "libinput",
+ "libui",
+ "libutils",
+ "libnativewindow",
+ "libvndksupport",
+ ],
+ header_libs: [
+ "libdvr_headers",
+ "libui_fuzzableDataspaces_headers",
+ ],
+ fuzz_config: {
+ cc: [
+ "android-media-fuzzing-reports@google.com",
+ ],
+ componentid: 155276,
+ },
+}
+
+cc_fuzz {
+ name: "libgui_surfaceComposer_fuzzer",
+ srcs: [
+ "libgui_surfaceComposer_fuzzer.cpp",
+ ],
+ defaults: [
+ "libgui_fuzzer_defaults",
+ ],
+}
+
+cc_fuzz {
+ name: "libgui_surfaceComposerClient_fuzzer",
+ srcs: [
+ "libgui_surfaceComposerClient_fuzzer.cpp",
+ ],
+ defaults: [
+ "libgui_fuzzer_defaults",
+ ],
+}
+
+cc_fuzz {
+ name: "libgui_parcelable_fuzzer",
+ srcs: [
+ "libgui_parcelable_fuzzer.cpp",
+ ],
+ defaults: [
+ "libgui_fuzzer_defaults",
+ ],
+}
+
+cc_fuzz {
+ name: "libgui_bufferQueue_fuzzer",
+ srcs: [
+ "libgui_bufferQueue_fuzzer.cpp",
+ ],
+ defaults: [
+ "libgui_fuzzer_defaults",
+ ],
+}
+
+cc_fuzz {
+ name: "libgui_consumer_fuzzer",
+ srcs: [
+ "libgui_consumer_fuzzer.cpp",
+ ],
+ defaults: [
+ "libgui_fuzzer_defaults",
+ ],
+}
+
+cc_fuzz {
+ name: "libgui_displayEvent_fuzzer",
+ srcs: [
+ "libgui_displayEvent_fuzzer.cpp",
+ ],
+ defaults: [
+ "libgui_fuzzer_defaults",
+ ],
+}
diff --git a/libs/gui/fuzzer/README.md b/libs/gui/fuzzer/README.md
new file mode 100644
index 0000000000..96e27c989f
--- /dev/null
+++ b/libs/gui/fuzzer/README.md
@@ -0,0 +1,219 @@
+# Fuzzers for Libgui
+
+## Table of contents
++ [libgui_surfaceComposer_fuzzer](#SurfaceComposer)
++ [libgui_surfaceComposerClient_fuzzer](#SurfaceComposerClient)
++ [libgui_parcelable_fuzzer](#Libgui_Parcelable)
++ [libgui_bufferQueue_fuzzer](#BufferQueue)
++ [libgui_consumer_fuzzer](#Libgui_Consumer)
++ [libgui_displayEvent_fuzzer](#LibGui_DisplayEvent)
+
+# <a name="libgui_surfaceComposer_fuzzer"></a> Fuzzer for SurfaceComposer
+
+SurfaceComposer supports the following parameters:
+1. SurfaceWidth (parameter name:`width`)
+2. SurfaceHeight (parameter name:`height`)
+3. TransactionStateFlags (parameter name:`flags`)
+4. TransformHint (parameter name:`outTransformHint`)
+5. SurfacePixelFormat (parameter name:`format`)
+6. LayerId (parameter name:`outLayerId`)
+7. SurfaceComposerTags (parameter name:`surfaceTag`)
+8. PowerBoostID (parameter name:`boostId`)
+9. VsyncSource (parameter name:`vsyncSource`)
+10. EventRegistrationFlags (parameter name:`eventRegistration`)
+11. FrameRateCompatibility (parameter name:`frameRateCompatibility`)
+12. ChangeFrameRateStrategy (parameter name:`changeFrameRateStrategy`)
+13. HdrTypes (parameter name:`hdrTypes`)
+
+| Parameter| Valid Values| Configured Value|
+|------------- |-------------| ----- |
+|`surfaceTag` | 0.`BnSurfaceComposer::BOOT_FINISHED`, 1.`BnSurfaceComposer::CREATE_CONNECTION`, 2.`BnSurfaceComposer::GET_STATIC_DISPLAY_INFO`, 3.`BnSurfaceComposer::CREATE_DISPLAY_EVENT_CONNECTION`, 4.`BnSurfaceComposer::CREATE_DISPLAY`, 5.`BnSurfaceComposer::DESTROY_DISPLAY`, 6.`BnSurfaceComposer::GET_PHYSICAL_DISPLAY_TOKEN`, 7.`BnSurfaceComposer::SET_TRANSACTION_STATE`, 8.`BnSurfaceComposer::AUTHENTICATE_SURFACE`, 9.`BnSurfaceComposer::GET_SUPPORTED_FRAME_TIMESTAMPS`, 10.`BnSurfaceComposer::GET_DISPLAY_STATE`, 11.`BnSurfaceComposer::CAPTURE_DISPLAY`, 12.`BnSurfaceComposer::CAPTURE_LAYERS`, 13.`BnSurfaceComposer::CLEAR_ANIMATION_FRAME_STATS`, 14.`BnSurfaceComposer::GET_ANIMATION_FRAME_STATS`, 15.`BnSurfaceComposer::SET_POWER_MODE`, 16.`BnSurfaceComposer::GET_DISPLAY_STATS`, 17.`BnSurfaceComposer::SET_ACTIVE_COLOR_MODE`, 18.`BnSurfaceComposer::ENABLE_VSYNC_INJECTIONS`, 19.`BnSurfaceComposer::INJECT_VSYNC`, 20.`BnSurfaceComposer::GET_LAYER_DEBUG_INFO`, 21.`BnSurfaceComposer::GET_COMPOSITION_PREFERENCE`, 22.`BnSurfaceComposer::GET_COLOR_MANAGEMENT`, 23.`BnSurfaceComposer::GET_DISPLAYED_CONTENT_SAMPLING_ATTRIBUTES`, 24.`BnSurfaceComposer::SET_DISPLAY_CONTENT_SAMPLING_ENABLED`, 25.`BnSurfaceComposer::GET_DISPLAYED_CONTENT_SAMPLE`, 26.`BnSurfaceComposer::GET_PROTECTED_CONTENT_SUPPORT`, 27.`BnSurfaceComposer::IS_WIDE_COLOR_DISPLAY`, 28.`BnSurfaceComposer::GET_DISPLAY_NATIVE_PRIMARIES`, 29.`BnSurfaceComposer::GET_PHYSICAL_DISPLAY_IDS`, 30.`BnSurfaceComposer::ADD_REGION_SAMPLING_LISTENER`, 31.`BnSurfaceComposer::REMOVE_REGION_SAMPLING_LISTENER`, 32.`BnSurfaceComposer::SET_DESIRED_DISPLAY_MODE_SPECS`, 33.`BnSurfaceComposer::GET_DESIRED_DISPLAY_MODE_SPECS`, 34.`BnSurfaceComposer::GET_DISPLAY_BRIGHTNESS_SUPPORT`, 35.`BnSurfaceComposer::SET_DISPLAY_BRIGHTNESS`, 36.`BnSurfaceComposer::CAPTURE_DISPLAY_BY_ID`, 37.`BnSurfaceComposer::NOTIFY_POWER_BOOST`, 38.`BnSurfaceComposer::SET_GLOBAL_SHADOW_SETTINGS`, 39.`BnSurfaceComposer::SET_AUTO_LOW_LATENCY_MODE`, 40.`BnSurfaceComposer::SET_GAME_CONTENT_TYPE`, 41.`BnSurfaceComposer::SET_FRAME_RATE`, 42.`BnSurfaceComposer::ACQUIRE_FRAME_RATE_FLEXIBILITY_TOKEN`, 43.`BnSurfaceComposer::SET_FRAME_TIMELINE_INFO`, 44.`BnSurfaceComposer::ADD_TRANSACTION_TRACE_LISTENER`, 45.`BnSurfaceComposer::GET_GPU_CONTEXT_PRIORITY`, 46.`BnSurfaceComposer::GET_MAX_ACQUIRED_BUFFER_COUNT`, 47.`BnSurfaceComposer::GET_DYNAMIC_DISPLAY_INFO`, 48.`BnSurfaceComposer::ADD_FPS_LISTENER`, 49.`BnSurfaceComposer::REMOVE_FPS_LISTENER`, 50.`BnSurfaceComposer::OVERRIDE_HDR_TYPES`, 51.`BnSurfaceComposer::ADD_HDR_LAYER_INFO_LISTENER`, 52.`BnSurfaceComposer::REMOVE_HDR_LAYER_INFO_LISTENER`, 53.`BnSurfaceComposer::ON_PULL_ATOM`, 54.`BnSurfaceComposer::ADD_TUNNEL_MODE_ENABLED_LISTENER`, 55.`BnSurfaceComposer::REMOVE_TUNNEL_MODE_ENABLED_LISTENER` | Value obtained from FuzzedDataProvider|
+|`boostId`| 0.`hardware::power::Boost::INTERACTION`, 1.`hardware::power::Boost::DISPLAY_UPDATE_IMMINENT`, 2.`hardware::power::Boost::ML_ACC`, 3.`hardware::power::Boost::AUDIO_LAUNCH`, 4.`hardware::power::Boost::CAMERA_LAUNCH`, 5.`hardware::power::Boost::CAMERA_SHOT` |Value obtained from FuzzedDataProvider|
+|`vsyncSource`| 0.`ISurfaceComposer::eVsyncSourceApp`, 1.`ISurfaceComposer::eVsyncSourceSurfaceFlinger`, |Value obtained from FuzzedDataProvider|
+|`eventRegistration`| 0.`ISurfaceComposer::EventRegistration::modeChanged`, 1.`ISurfaceComposer::EventRegistration::frameRateOverride` |Value obtained from FuzzedDataProvider|
+|`frameRateCompatibility`| 0.`ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_DEFAULT`, 1.`ANATIVEWINDOW_FRAME_RATE_COMPATIBILITY_FIXED_SOURCE` |Value obtained from FuzzedDataProvider|
+|`changeFrameRateStrategy`| 0.`ANATIVEWINDOW_CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS`, 1.`ANATIVEWINDOW_CHANGE_FRAME_RATE_ALWAYS` |Value obtained from FuzzedDataProvider|
+|`hdrTypes`| 0.`ui::Hdr::DOLBY_VISION`, 1.`ui::Hdr::HDR10`, 2.`ui::Hdr::HLG`, 3.`ui::Hdr::HDR10_PLUS` |Value obtained from FuzzedDataProvider|
+
+#### Steps to run
+1. Build the fuzzer
+```
+ $ mm -j$(nproc) libgui_surfaceComposer_fuzzer
+```
+2. Run on device
+```
+ $ adb sync data
+ $ adb shell /data/fuzz/arm64/libgui_surfaceComposer_fuzzer/libgui_surfaceComposer_fuzzer
+```
+
+# <a name="libgui_surfaceComposerClient_fuzzer"></a> Fuzzer for SurfaceComposerClient
+
+SurfaceComposerClient supports the following data sources:
+1. SurfaceWidth (parameter name:`width`)
+2. SurfaceHeight (parameter name:`height`)
+3. TransactionStateFlags (parameter name:`flags`)
+4. TransformHint (parameter name:`outTransformHint`)
+5. SurfacePixelFormat (parameter name:`format`)
+6. LayerId (parameter name:`outLayerId`)
+7. SurfaceComposerClientTags (parameter name:`surfaceTag`)
+8. DefaultMode (parameter name:`defaultMode`)
+9. PrimaryRefreshRateMin (parameter name:`primaryRefreshRateMin`)
+10. PrimaryRefreshRateMax (parameter name:`primaryRefreshRateMax`)
+11. AppRefreshRateMin (parameter name:`appRefreshRateMin`)
+12. AppRefreshRateMax (parameter name:`appRefreshRateMax`)
+13. DisplayPowerMode (parameter name:`mode`)
+14. CacheId (parameter name:`cacheId`)
+15. DisplayBrightness (parameter name:`brightness`)
+16. PowerBoostID (parameter name:`boostId`)
+17. AtomId (parameter name:`atomId`)
+18. ComponentMask (parameter name:`componentMask`)
+19. MaxFrames (parameter name:`maxFrames`)
+20. TaskId (parameter name:`taskId`)
+21. Alpha (parameter name:`aplha`)
+22. CornerRadius (parameter name:`cornerRadius`)
+23. BackgroundBlurRadius (parameter name:`backgroundBlurRadius`)
+24. Half3Color (parameter name:`color`)
+25. LayerStack (parameter name:`layerStack`)
+26. Dataspace (parameter name:`dataspace`)
+27. Api (parameter name:`api`)
+28. Priority (parameter name:`priority`)
+29. TouchableRegionPointX (parameter name:`pointX`)
+30. TouchableRegionPointY (parameter name:`pointY`)
+31. ColorMode (parameter name:`colorMode`)
+32. WindowInfoFlags (parameter name:`flags`)
+33. WindowInfoTransformOrientation (parameter name:`transform`)
+
+| Parameter| Valid Values| Configured Value|
+|------------- |-------------| ----- |
+|`surfaceTag`| 0.`Tag::CREATE_SURFACE`, 1.`Tag::CREATE_WITH_SURFACE_PARENT`, 2.`Tag::CLEAR_LAYER_FRAME_STATS`, 3.`Tag::GET_LAYER_FRAME_STATS`, 4.`Tag::MIRROR_SURFACE`, 5.`Tag::LAST` |Value obtained from FuzzedDataProvider|
+|`mode`| 0.`gui::TouchOcclusionMode::BLOCK_UNTRUSTED`, 1.`gui::TouchOcclusionMode::USE_OPACITY`, 2.`gui::TouchOcclusionMode::ALLOW` |Value obtained from FuzzedDataProvider|
+|`boostId`| 0.`hardware::power::Boost::INTERACTION`, 1.`hardware::power::Boost::DISPLAY_UPDATE_IMMINENT`, 2.`hardware::power::Boost::ML_ACC`, 3.`hardware::power::Boost::AUDIO_LAUNCH`, 4.`hardware::power::Boost::CAMERA_LAUNCH`, 5.`hardware::power::Boost::CAMERA_SHOT` |Value obtained from FuzzedDataProvider|
+|`colorMode`|0.`ui::ColorMode::NATIVE`, 1.`ui::ColorMode::STANDARD_BT601_625`, 2.`ui::ColorMode::STANDARD_BT601_625_UNADJUSTED`, 3.`ui::ColorMode::STANDARD_BT601_525`, 4.`ui::ColorMode::STANDARD_BT601_525_UNADJUSTED`, 5.`ui::ColorMode::STANDARD_BT709`, 6.`ui::ColorMode::DCI_P3`, 7.`ui::ColorMode::SRGB`, 8.`ui::ColorMode::ADOBE_RGB`, 9.`ui::ColorMode::DISPLAY_P3`, 10.`ui::ColorMode::BT2020`, 11.`ui::ColorMode::BT2100_PQ`, 12.`ui::ColorMode::BT2100_HLG`, 13.`ui::ColorMode::DISPLAY_BT2020` |Value obtained from FuzzedDataProvider|
+|`flags`|0 .`gui::WindowInfo::Flag::ALLOW_LOCK_WHILE_SCREEN_ON`, 1.`gui::WindowInfo::Flag::DIM_BEHIND`, 2.`gui::WindowInfo::Flag::BLUR_BEHIND`, 3.`gui::WindowInfo::Flag::NOT_FOCUSABLE`, 4.`gui::WindowInfo::Flag::NOT_TOUCHABLE`, 5.`gui::WindowInfo::Flag::NOT_TOUCH_MODAL`, 6.`gui::WindowInfo::Flag::TOUCHABLE_WHEN_WAKING`, 7.`gui::WindowInfo::Flag::KEEP_SCREEN_ON`, 8.`gui::WindowInfo::Flag::LAYOUT_IN_SCREEN`, 9.`gui::WindowInfo::Flag::LAYOUT_NO_LIMITS`, 10.`gui::WindowInfo::Flag::FULLSCREEN`, 11.`gui::WindowInfo::Flag::FORCE_NOT_FULLSCREEN`, 12.`gui::WindowInfo::Flag::DITHER`, 13.`gui::WindowInfo::Flag::SECURE`, 14.`gui::WindowInfo::Flag::SCALED`, 15.`gui::WindowInfo::Flag::IGNORE_CHEEK_PRESSES`, 16.`gui::WindowInfo::Flag::LAYOUT_INSET_DECOR`, 17.`gui::WindowInfo::Flag::ALT_FOCUSABLE_IM`, 18.`gui::WindowInfo::Flag::WATCH_OUTSIDE_TOUCH`, 19.`gui::WindowInfo::Flag::SHOW_WHEN_LOCKED`, 20.`gui::WindowInfo::Flag::SHOW_WALLPAPER`, 21.`gui::WindowInfo::Flag::TURN_SCREEN_ON`, 22.`gui::WindowInfo::Flag::DISMISS_KEYGUARD`, 23.`gui::WindowInfo::Flag::SPLIT_TOUCH`, 24.`gui::WindowInfo::Flag::HARDWARE_ACCELERATED`, 25.`gui::WindowInfo::Flag::LAYOUT_IN_OVERSCAN`, 26.`gui::WindowInfo::Flag::TRANSLUCENT_STATUS`, 27.`gui::WindowInfo::Flag::TRANSLUCENT_NAVIGATION`, 28.`gui::WindowInfo::Flag::LOCAL_FOCUS_MODE`, 29.`gui::WindowInfo::Flag::SLIPPERY`, 30.`gui::WindowInfo::Flag::LAYOUT_ATTACHED_IN_DECOR`, 31.`gui::WindowInfo::Flag::DRAWS_SYSTEM_BAR_BACKGROUNDS`, |Value obtained from FuzzedDataProvider|
+|`dataspace`| 0.`ui::Dataspace::UNKNOWN`, 1.`ui::Dataspace::ARBITRARY`, 2.`ui::Dataspace::STANDARD_SHIFT`, 3.`ui::Dataspace::STANDARD_MASK`, 4.`ui::Dataspace::STANDARD_UNSPECIFIED`, 5.`ui::Dataspace::STANDARD_BT709`, 6.`ui::Dataspace::STANDARD_BT601_625`, 7.`ui::Dataspace::STANDARD_BT601_625_UNADJUSTED`, 8.`ui::Dataspace::STANDARD_BT601_525`, 9.`ui::Dataspace::STANDARD_BT601_525_UNADJUSTED`, 10.`ui::Dataspace::STANDARD_BT2020`, 11.`ui::Dataspace::STANDARD_BT2020_CONSTANT_LUMINANCE`, 12.`ui::Dataspace::STANDARD_BT470M`, 13.`ui::Dataspace::STANDARD_FILM`, 14.`ui::Dataspace::STANDARD_DCI_P3`, 15.`ui::Dataspace::STANDARD_ADOBE_RGB`, 16.`ui::Dataspace::TRANSFER_SHIFT`, 17.`ui::Dataspace::TRANSFER_MASK`, 18.`ui::Dataspace::TRANSFER_UNSPECIFIED`, 19.`ui::Dataspace::TRANSFER_LINEAR`, 20.`ui::Dataspace::TRANSFER_SRGB`, 21.`ui::Dataspace::TRANSFER_SMPTE_170M`, 22.`ui::Dataspace::TRANSFER_GAMMA2_2`, 23.`ui::Dataspace::TRANSFER_GAMMA2_6`, 24.`ui::Dataspace::TRANSFER_GAMMA2_8`, 25.`ui::Dataspace::TRANSFER_ST2084`, 26.`ui::Dataspace::TRANSFER_HLG`, 27.`ui::Dataspace::RANGE_SHIFT`, 28.`ui::Dataspace::RANGE_MASK`, 29.`ui::Dataspace::RANGE_UNSPECIFIED`, 30.`ui::Dataspace::RANGE_FULL`, 31.`ui::Dataspace::RANGE_LIMITED`, 32.`ui::Dataspace::RANGE_EXTENDED`, 33.`ui::Dataspace::SRGB_LINEAR`, 34.`ui::Dataspace::V0_SRGB_LINEAR`, 35.`ui::Dataspace::V0_SCRGB_LINEAR`, 36.`ui::Dataspace::SRGB`, 37.`ui::Dataspace::V0_SRGB`, 38.`ui::Dataspace::V0_SCRGB`, 39.`ui::Dataspace::JFIF`, 40.`ui::Dataspace::V0_JFIF`, 41.`ui::Dataspace::BT601_625`, 42.`ui::Dataspace::V0_BT601_625`, 43.`ui::Dataspace::BT601_525`, 44.`ui::Dataspace::V0_BT601_525`, 45.`ui::Dataspace::BT709`, 46.`ui::Dataspace::V0_BT709`, 47.`ui::Dataspace::DCI_P3_LINEAR`, 48.`ui::Dataspace::DCI_P3`, 49.`ui::Dataspace::DISPLAY_P3_LINEAR`, 50.`ui::Dataspace::DISPLAY_P3`, 51.`ui::Dataspace::ADOBE_RGB`, 52.`ui::Dataspace::BT2020_LINEAR`, 53.`ui::Dataspace::BT2020`, 54.`ui::Dataspace::BT2020_PQ`, 55.`ui::Dataspace::DEPTH`, 56.`ui::Dataspace::SENSOR`, 57.`ui::Dataspace::BT2020_ITU`, 58.`ui::Dataspace::BT2020_ITU_PQ`, 59.`ui::Dataspace::BT2020_ITU_HLG`, 60.`ui::Dataspace::BT2020_HLG`, 61.`ui::Dataspace::DISPLAY_BT2020`, 62.`ui::Dataspace::DYNAMIC_DEPTH`, 63.`ui::Dataspace::JPEG_APP_SEGMENTS`, 64.`ui::Dataspace::HEIF`, |Value obtained from FuzzedDataProvider|
+|`transform`| 0.`ui::Transform::ROT_0`, 1.`ui::Transform::FLIP_H`, 2.`ui::Transform::FLIP_V`, 3.`ui::Transform::ROT_90`, 4.`ui::Transform::ROT_180`, 5.`ui::Transform::ROT_270` |Value obtained from FuzzedDataProvider|
+
+#### Steps to run
+1. Build the fuzzer
+```
+ $ mm -j$(nproc) libgui_surfaceComposerClient_fuzzer
+```
+2. To run on device
+```
+ $ adb sync data
+ $ adb shell /data/fuzz/arm64/libgui_surfaceComposerClient_fuzzer/libgui_surfaceComposerClient_fuzzer
+```
+
+# <a name="libgui_parcelable_fuzzer"></a> Fuzzer for Libgui_Parcelable
+
+Libgui_Parcelable supports the following parameters:
+1. LayerMetadataKey (parameter name:`key`)
+2. Dataspace (parameter name:`mDataspace`)
+
+| Parameter| Valid Values| Configured Value|
+|------------- |-------------| ----- |
+|`key`| 0.`view::LayerMetadataKey::METADATA_OWNER_UID`, 1.`view::LayerMetadataKey::METADATA_WINDOW_TYPE`, 2.`view::LayerMetadataKey::METADATA_TASK_ID`, 3.`view::LayerMetadataKey::METADATA_MOUSE_CURSOR`, 4.`view::LayerMetadataKey::METADATA_ACCESSIBILITY_ID`, 5.`view::LayerMetadataKey::METADATA_OWNER_PID`, 6.`view::LayerMetadataKey::METADATA_DEQUEUE_TIME`, 7.`view::LayerMetadataKey::METADATA_GAME_MODE`, |Value obtained from FuzzedDataProvider|
+|`mDataSpace`| 0.`ui::Dataspace::UNKNOWN`, 1.`ui::Dataspace::ARBITRARY`, 2.`ui::Dataspace::STANDARD_SHIFT`, 3.`ui::Dataspace::STANDARD_MASK`, 4.`ui::Dataspace::STANDARD_UNSPECIFIED`, 5.`ui::Dataspace::STANDARD_BT709`, 6.`ui::Dataspace::STANDARD_BT601_625`, 7.`ui::Dataspace::STANDARD_BT601_625_UNADJUSTED`, 8.`ui::Dataspace::STANDARD_BT601_525`, 9.`ui::Dataspace::STANDARD_BT601_525_UNADJUSTED`, 10.`ui::Dataspace::STANDARD_BT2020`, 11.`ui::Dataspace::STANDARD_BT2020_CONSTANT_LUMINANCE`, 12.`ui::Dataspace::STANDARD_BT470M`, 13.`ui::Dataspace::STANDARD_FILM`, 14.`ui::Dataspace::STANDARD_DCI_P3`, 15.`ui::Dataspace::STANDARD_ADOBE_RGB`, 16.`ui::Dataspace::TRANSFER_SHIFT`, 17.`ui::Dataspace::TRANSFER_MASK`, 18.`ui::Dataspace::TRANSFER_UNSPECIFIED`, 19.`ui::Dataspace::TRANSFER_LINEAR`, 20.`ui::Dataspace::TRANSFER_SRGB`, 21.`ui::Dataspace::TRANSFER_SMPTE_170M`, 22.`ui::Dataspace::TRANSFER_GAMMA2_2`, 23.`ui::Dataspace::TRANSFER_GAMMA2_6`, 24.`ui::Dataspace::TRANSFER_GAMMA2_8`, 25.`ui::Dataspace::TRANSFER_ST2084`, 26.`ui::Dataspace::TRANSFER_HLG`, 27.`ui::Dataspace::RANGE_SHIFT`, 28.`ui::Dataspace::RANGE_MASK`, 29.`ui::Dataspace::RANGE_UNSPECIFIED`, 30.`ui::Dataspace::RANGE_FULL`, 31.`ui::Dataspace::RANGE_LIMITED`, 32.`ui::Dataspace::RANGE_EXTENDED`, 33.`ui::Dataspace::SRGB_LINEAR`, 34.`ui::Dataspace::V0_SRGB_LINEAR`, 35.`ui::Dataspace::V0_SCRGB_LINEAR`, 36.`ui::Dataspace::SRGB`, 37.`ui::Dataspace::V0_SRGB`, 38.`ui::Dataspace::V0_SCRGB`, 39.`ui::Dataspace::JFIF`, 40.`ui::Dataspace::V0_JFIF`, 41.`ui::Dataspace::BT601_625`, 42.`ui::Dataspace::V0_BT601_625`, 43.`ui::Dataspace::BT601_525`, 44.`ui::Dataspace::V0_BT601_525`, 45.`ui::Dataspace::BT709`, 46.`ui::Dataspace::V0_BT709`, 47.`ui::Dataspace::DCI_P3_LINEAR`, 48.`ui::Dataspace::DCI_P3`, 49.`ui::Dataspace::DISPLAY_P3_LINEAR`, 50.`ui::Dataspace::DISPLAY_P3`, 51.`ui::Dataspace::ADOBE_RGB`, 52.`ui::Dataspace::BT2020_LINEAR`, 53.`ui::Dataspace::BT2020`, 54.`ui::Dataspace::BT2020_PQ`, 55.`ui::Dataspace::DEPTH`, 56.`ui::Dataspace::SENSOR`, 57.`ui::Dataspace::BT2020_ITU`, 58.`ui::Dataspace::BT2020_ITU_PQ`, 59.`ui::Dataspace::BT2020_ITU_HLG`, 60.`ui::Dataspace::BT2020_HLG`, 61.`ui::Dataspace::DISPLAY_BT2020`, 62.`ui::Dataspace::DYNAMIC_DEPTH`, 63.`ui::Dataspace::JPEG_APP_SEGMENTS`, 64.`ui::Dataspace::HEIF`, |Value obtained from FuzzedDataProvider|
+
+#### Steps to run
+1. Build the fuzzer
+```
+ $ mm -j$(nproc) libgui_fuzzer
+```
+2. Run on device
+```
+ $ adb sync data
+ $ adb shell /data/fuzz/arm64/libgui_fuzzer/libgui_fuzzer
+```
+
+# <a name="libgui_bufferQueue_fuzzer"></a> Fuzzer for BufferQueue
+
+BufferQueue supports the following parameters:
+1. SurfaceWidth (parameter name:`width`)
+2. SurfaceHeight (parameter name:`height`)
+3. TransactionStateFlags (parameter name:`flags`)
+4. TransformHint (parameter name:`outTransformHint`)
+5. SurfacePixelFormat (parameter name:`format`)
+6. LayerId (parameter name:`layerId`)
+7. BufferId (parameter name:`bufferId`)
+8. FrameNumber (parameter name:`frameNumber`)
+9. FrameRate (parameter name:`frameRate`)
+10. Compatability (parameter name:`compatability`)
+11. LatchTime (parameter name:`latchTime`)
+12. AcquireTime (parameter name:`acquireTime`)
+13. RefreshTime (parameter name:`refreshTime`)
+14. DequeueTime (parameter name:`dequeueTime`)
+15. Slot (parameter name:`slot`)
+16. MaxBuffers (parameter name:`maxBuffers`)
+17. GenerationNumber (parameter name:`generationNumber`)
+18. Api (parameter name:`api`)
+19. Usage (parameter name:`usage`)
+20. MaxFrameNumber (parameter name:`maxFrameNumber`)
+21. BufferCount (parameter name:`bufferCount`)
+22. MaxAcquredBufferCount (parameter name:`maxAcquredBufferCount`)
+23. Status (parameter name:`status`)
+24. ApiConnection (parameter name:`apiConnection`)
+25. Dataspace (parameter name:`dataspace`)
+
+| Parameter| Valid Values| Configured Value|
+|------------- |-------------| ----- |
+|`status`| 0.`OK`, 1.`NO_MEMORY`, 2.`NO_INIT`, 3.`BAD_VALUE`, 4.`DEAD_OBJECT`, 5.`INVALID_OPERATION`, 6.`TIMED_OUT`, 7.`WOULD_BLOCK`, 8.`UNKNOWN_ERROR`, 9.`ALREADY_EXISTS`, |Value obtained from FuzzedDataProvider|
+|`apiConnection`| 0.`BufferQueueCore::CURRENTLY_CONNECTED_API`, 1.`BufferQueueCore::NO_CONNECTED_API`, 2.`NATIVE_WINDOW_API_EGL`, 3.`NATIVE_WINDOW_API_CPU`, 4.`NATIVE_WINDOW_API_MEDIA`, 5.`NATIVE_WINDOW_API_CAMERA`, |Value obtained from FuzzedDataProvider|
+|`dataspace`| 0.`ui::Dataspace::UNKNOWN`, 1.`ui::Dataspace::ARBITRARY`, 2.`ui::Dataspace::STANDARD_SHIFT`, 3.`ui::Dataspace::STANDARD_MASK`, 4.`ui::Dataspace::STANDARD_UNSPECIFIED`, 5.`ui::Dataspace::STANDARD_BT709`, 6.`ui::Dataspace::STANDARD_BT601_625`, 7.`ui::Dataspace::STANDARD_BT601_625_UNADJUSTED`, 8.`ui::Dataspace::STANDARD_BT601_525`, 9.`ui::Dataspace::STANDARD_BT601_525_UNADJUSTED`, 10.`ui::Dataspace::STANDARD_BT2020`, 11.`ui::Dataspace::STANDARD_BT2020_CONSTANT_LUMINANCE`, 12.`ui::Dataspace::STANDARD_BT470M`, 13.`ui::Dataspace::STANDARD_FILM`, 14.`ui::Dataspace::STANDARD_DCI_P3`, 15.`ui::Dataspace::STANDARD_ADOBE_RGB`, 16.`ui::Dataspace::TRANSFER_SHIFT`, 17.`ui::Dataspace::TRANSFER_MASK`, 18.`ui::Dataspace::TRANSFER_UNSPECIFIED`, 19.`ui::Dataspace::TRANSFER_LINEAR`, 20.`ui::Dataspace::TRANSFER_SRGB`, 21.`ui::Dataspace::TRANSFER_SMPTE_170M`, 22.`ui::Dataspace::TRANSFER_GAMMA2_2`, 23.`ui::Dataspace::TRANSFER_GAMMA2_6`, 24.`ui::Dataspace::TRANSFER_GAMMA2_8`, 25.`ui::Dataspace::TRANSFER_ST2084`, 26.`ui::Dataspace::TRANSFER_HLG`, 27.`ui::Dataspace::RANGE_SHIFT`, 28.`ui::Dataspace::RANGE_MASK`, 29.`ui::Dataspace::RANGE_UNSPECIFIED`, 30.`ui::Dataspace::RANGE_FULL`, 31.`ui::Dataspace::RANGE_LIMITED`, 32.`ui::Dataspace::RANGE_EXTENDED`, 33.`ui::Dataspace::SRGB_LINEAR`, 34.`ui::Dataspace::V0_SRGB_LINEAR`, 35.`ui::Dataspace::V0_SCRGB_LINEAR`, 36.`ui::Dataspace::SRGB`, 37.`ui::Dataspace::V0_SRGB`, 38.`ui::Dataspace::V0_SCRGB`, 39.`ui::Dataspace::JFIF`, 40.`ui::Dataspace::V0_JFIF`, 41.`ui::Dataspace::BT601_625`, 42.`ui::Dataspace::V0_BT601_625`, 43.`ui::Dataspace::BT601_525`, 44.`ui::Dataspace::V0_BT601_525`, 45.`ui::Dataspace::BT709`, 46.`ui::Dataspace::V0_BT709`, 47.`ui::Dataspace::DCI_P3_LINEAR`, 48.`ui::Dataspace::DCI_P3`, 49.`ui::Dataspace::DISPLAY_P3_LINEAR`, 50.`ui::Dataspace::DISPLAY_P3`, 51.`ui::Dataspace::ADOBE_RGB`, 52.`ui::Dataspace::BT2020_LINEAR`, 53.`ui::Dataspace::BT2020`, 54.`ui::Dataspace::BT2020_PQ`, 55.`ui::Dataspace::DEPTH`, 56.`ui::Dataspace::SENSOR`, 57.`ui::Dataspace::BT2020_ITU`, 58.`ui::Dataspace::BT2020_ITU_PQ`, 59.`ui::Dataspace::BT2020_ITU_HLG`, 60.`ui::Dataspace::BT2020_HLG`, 61.`ui::Dataspace::DISPLAY_BT2020`, 62.`ui::Dataspace::DYNAMIC_DEPTH`, 63.`ui::Dataspace::JPEG_APP_SEGMENTS`, 64.`ui::Dataspace::HEIF`, |Value obtained from FuzzedDataProvider|
+
+#### Steps to run
+1. Build the fuzzer
+```
+ $ mm -j$(nproc) libgui_bufferQueue_fuzzer
+```
+2. To run on device
+```
+ $ adb sync data
+ $ adb shell /data/fuzz/arm64/libgui_bufferQueue_fuzzer/libgui_bufferQueue_fuzzer
+```
+
+# <a name="libgui_consumer_fuzzer"></a> Fuzzer for Libgui_Consumer
+
+Libgui_Consumer supports the following parameters:
+1. GraphicWidth (parameter name:`graphicWidth`)
+2. GraphicHeight (parameter name:`graphicHeight`)
+4. TransformHint (parameter name:`outTransformHint`)
+5. GraphicPixelFormat (parameter name:`format`)
+6. Usage (parameter name:`usage`)
+
+#### Steps to run
+1. Build the fuzzer
+```
+ $ mm -j$(nproc) libgui_consumer_fuzzer
+```
+2. Run on device
+```
+ $ adb sync data
+ $ adb shell /data/fuzz/arm64/libgui_consumer_fuzzer/libgui_consumer_fuzzer
+```
+
+# <a name="libgui_displayEvent_fuzzer"></a> Fuzzer for LibGui_DisplayEvent
+
+LibGui_DisplayEvent supports the following parameters:
+1. DisplayEventType (parameter name:`type`)
+2. Events (parameter name:`events`)
+3. VsyncSource (parameter name:`vsyncSource`)
+4. EventRegistrationFlags (parameter name:`flags`)
+
+| Parameter| Valid Values| Configured Value|
+|------------- |-------------| ----- |
+|`vsyncSource`| 0.`ISurfaceComposer::eVsyncSourceApp`, 1.`ISurfaceComposer::eVsyncSourceSurfaceFlinger`, |Value obtained from FuzzedDataProvider|
+|`flags`| 0.`ISurfaceComposer::EventRegistration::modeChanged`, 1.`ISurfaceComposer::EventRegistration::frameRateOverride`, |Value obtained from FuzzedDataProvider|
+|`type`| 0.`DisplayEventReceiver::DISPLAY_EVENT_NULL`, 1.`DisplayEventReceiver::DISPLAY_EVENT_VSYNC`, 2.`DisplayEventReceiver::DISPLAY_EVENT_HOTPLUG`, 3.`DisplayEventReceiver::DISPLAY_EVENT_MODE_CHANGE`, 4.`DisplayEventReceiver::DISPLAY_EVENT_FRAME_RATE_OVERRIDE`, 5.`DisplayEventReceiver::DISPLAY_EVENT_FRAME_RATE_OVERRIDE_FLUSH`, |Value obtained from FuzzedDataProvider|
+|`events`| 0.`Looper::EVENT_INPUT`, 1.`Looper::EVENT_OUTPUT`, 2.`Looper::EVENT_ERROR`, 3.`Looper::EVENT_HANGUP`, 4.`Looper::EVENT_INVALID`, |Value obtained from FuzzedDataProvider|
+
+#### Steps to run
+1. Build the fuzzer
+```
+ $ mm -j$(nproc) libgui_displayEvent_fuzzer
+```
+2. Run on device
+```
+ $ adb sync data
+ $ adb shell /data/fuzz/arm64/libgui_displayEvent_fuzzer/libgui_displayEvent_fuzzer
+```
diff --git a/libs/gui/fuzzer/libgui_bufferQueue_fuzzer.cpp b/libs/gui/fuzzer/libgui_bufferQueue_fuzzer.cpp
new file mode 100644
index 0000000000..17f4c630ce
--- /dev/null
+++ b/libs/gui/fuzzer/libgui_bufferQueue_fuzzer.cpp
@@ -0,0 +1,392 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <android-base/stringprintf.h>
+#include <gui/BufferQueueConsumer.h>
+#include <gui/BufferQueueCore.h>
+#include <gui/BufferQueueProducer.h>
+#include <gui/bufferqueue/2.0/types.h>
+#include <system/window.h>
+
+#include <libgui_fuzzer_utils.h>
+
+using namespace android;
+using namespace hardware::graphics::bufferqueue;
+using namespace V1_0::utils;
+using namespace V2_0::utils;
+
+constexpr int32_t kMaxBytes = 256;
+
+constexpr int32_t kError[] = {
+ OK, NO_MEMORY, NO_INIT, BAD_VALUE, DEAD_OBJECT, INVALID_OPERATION,
+ TIMED_OUT, WOULD_BLOCK, UNKNOWN_ERROR, ALREADY_EXISTS,
+};
+
+constexpr int32_t kAPIConnection[] = {
+ BufferQueueCore::CURRENTLY_CONNECTED_API,
+ BufferQueueCore::NO_CONNECTED_API,
+ NATIVE_WINDOW_API_EGL,
+ NATIVE_WINDOW_API_CPU,
+ NATIVE_WINDOW_API_MEDIA,
+ NATIVE_WINDOW_API_CAMERA,
+};
+
+class BufferQueueFuzzer {
+public:
+ BufferQueueFuzzer(const uint8_t* data, size_t size) : mFdp(data, size){};
+ void process();
+
+private:
+ void invokeTypes();
+ void invokeH2BGraphicBufferV1();
+ void invokeH2BGraphicBufferV2();
+ void invokeBufferQueueConsumer();
+ void invokeBufferQueueProducer();
+ void invokeBlastBufferQueue();
+ void invokeQuery(sp<BufferQueueProducer>);
+ void invokeQuery(sp<V1_0::utils::H2BGraphicBufferProducer>);
+ void invokeQuery(sp<V2_0::utils::H2BGraphicBufferProducer>);
+ void invokeAcquireBuffer(sp<BufferQueueConsumer>);
+ void invokeOccupancyTracker(sp<BufferQueueConsumer>);
+ sp<SurfaceControl> makeSurfaceControl();
+ sp<BLASTBufferQueue> makeBLASTBufferQueue(sp<SurfaceControl>);
+
+ FuzzedDataProvider mFdp;
+};
+
+class ManageResourceHandle {
+public:
+ ManageResourceHandle(FuzzedDataProvider* fdp) {
+ mNativeHandle = native_handle_create(0 /*numFds*/, 1 /*numInts*/);
+ mShouldOwn = fdp->ConsumeBool();
+ mStream = NativeHandle::create(mNativeHandle, mShouldOwn);
+ }
+ ~ManageResourceHandle() {
+ if (!mShouldOwn) {
+ native_handle_close(mNativeHandle);
+ native_handle_delete(mNativeHandle);
+ }
+ }
+ sp<NativeHandle> getStream() { return mStream; }
+
+private:
+ bool mShouldOwn;
+ sp<NativeHandle> mStream;
+ native_handle_t* mNativeHandle;
+};
+
+sp<SurfaceControl> BufferQueueFuzzer::makeSurfaceControl() {
+ sp<IBinder> handle;
+ const sp<FakeBnSurfaceComposerClient> testClient(new FakeBnSurfaceComposerClient());
+ sp<SurfaceComposerClient> client = new SurfaceComposerClient(testClient);
+ sp<BnGraphicBufferProducer> producer;
+ uint32_t layerId = mFdp.ConsumeIntegral<uint32_t>();
+ std::string layerName = base::StringPrintf("#%d", layerId);
+ return sp<SurfaceControl>::make(client, handle, layerId, layerName,
+ mFdp.ConsumeIntegral<int32_t>(),
+ mFdp.ConsumeIntegral<uint32_t>(),
+ mFdp.ConsumeIntegral<int32_t>(),
+ mFdp.ConsumeIntegral<uint32_t>(),
+ mFdp.ConsumeIntegral<uint32_t>());
+}
+
+sp<BLASTBufferQueue> BufferQueueFuzzer::makeBLASTBufferQueue(sp<SurfaceControl> surface) {
+ return sp<BLASTBufferQueue>::make(mFdp.ConsumeRandomLengthString(kMaxBytes), surface,
+ mFdp.ConsumeIntegral<uint32_t>(),
+ mFdp.ConsumeIntegral<uint32_t>(),
+ mFdp.ConsumeIntegral<int32_t>());
+}
+
+void BufferQueueFuzzer::invokeBlastBufferQueue() {
+ sp<SurfaceControl> surface = makeSurfaceControl();
+ sp<BLASTBufferQueue> queue = makeBLASTBufferQueue(surface);
+
+ BufferItem item;
+ queue->onFrameAvailable(item);
+ queue->onFrameReplaced(item);
+ uint64_t bufferId = mFdp.ConsumeIntegral<uint64_t>();
+ queue->onFrameDequeued(bufferId);
+ queue->onFrameCancelled(bufferId);
+
+ SurfaceComposerClient::Transaction next;
+ uint64_t frameNumber = mFdp.ConsumeIntegral<uint64_t>();
+ queue->mergeWithNextTransaction(&next, frameNumber);
+ queue->applyPendingTransactions(frameNumber);
+
+ queue->update(surface, mFdp.ConsumeIntegral<uint32_t>(), mFdp.ConsumeIntegral<uint32_t>(),
+ mFdp.ConsumeIntegral<int32_t>());
+ queue->setFrameRate(mFdp.ConsumeFloatingPoint<float>(), mFdp.ConsumeIntegral<int8_t>(),
+ mFdp.ConsumeBool() /*shouldBeSeamless*/);
+ FrameTimelineInfo info;
+ queue->setFrameTimelineInfo(mFdp.ConsumeIntegral<uint64_t>(), info);
+
+ ManageResourceHandle handle(&mFdp);
+ queue->setSidebandStream(handle.getStream());
+
+ queue->getLastTransformHint();
+ queue->getLastAcquiredFrameNum();
+
+ CompositorTiming compTiming;
+ sp<Fence> previousFence = new Fence(memfd_create("pfd", MFD_ALLOW_SEALING));
+ sp<Fence> gpuFence = new Fence(memfd_create("gfd", MFD_ALLOW_SEALING));
+ FrameEventHistoryStats frameStats(frameNumber, gpuFence, compTiming,
+ mFdp.ConsumeIntegral<int64_t>(),
+ mFdp.ConsumeIntegral<int64_t>());
+ std::vector<SurfaceControlStats> stats;
+ sp<Fence> presentFence = new Fence(memfd_create("fd", MFD_ALLOW_SEALING));
+ SurfaceControlStats controlStats(surface, mFdp.ConsumeIntegral<int64_t>(),
+ mFdp.ConsumeIntegral<int64_t>(), presentFence, previousFence,
+ mFdp.ConsumeIntegral<uint32_t>(), frameStats,
+ mFdp.ConsumeIntegral<uint32_t>());
+ stats.push_back(controlStats);
+}
+
+void BufferQueueFuzzer::invokeQuery(sp<BufferQueueProducer> producer) {
+ int32_t value;
+ producer->query(mFdp.ConsumeIntegral<int32_t>(), &value);
+}
+
+void BufferQueueFuzzer::invokeQuery(sp<V1_0::utils::H2BGraphicBufferProducer> producer) {
+ int32_t value;
+ producer->query(mFdp.ConsumeIntegral<int32_t>(), &value);
+}
+
+void BufferQueueFuzzer::invokeQuery(sp<V2_0::utils::H2BGraphicBufferProducer> producer) {
+ int32_t value;
+ producer->query(mFdp.ConsumeIntegral<int32_t>(), &value);
+}
+
+void BufferQueueFuzzer::invokeBufferQueueProducer() {
+ sp<BufferQueueCore> core(new BufferQueueCore());
+ sp<BufferQueueProducer> producer(new BufferQueueProducer(core));
+ const sp<android::IProducerListener> listener;
+ android::IGraphicBufferProducer::QueueBufferOutput output;
+ uint32_t api = mFdp.ConsumeIntegral<uint32_t>();
+ producer->connect(listener, api, mFdp.ConsumeBool() /*producerControlledByApp*/, &output);
+
+ sp<GraphicBuffer> buffer;
+ int32_t slot = mFdp.ConsumeIntegral<int32_t>();
+ uint32_t maxBuffers = mFdp.ConsumeIntegral<uint32_t>();
+ producer->requestBuffer(slot, &buffer);
+ producer->setMaxDequeuedBufferCount(maxBuffers);
+ producer->setAsyncMode(mFdp.ConsumeBool() /*async*/);
+
+ android::IGraphicBufferProducer::QueueBufferInput input;
+ producer->attachBuffer(&slot, buffer);
+ producer->queueBuffer(slot, input, &output);
+
+ int32_t format = mFdp.ConsumeIntegral<int32_t>();
+ uint32_t width = mFdp.ConsumeIntegral<uint32_t>();
+ uint32_t height = mFdp.ConsumeIntegral<uint32_t>();
+ uint64_t usage = mFdp.ConsumeIntegral<uint64_t>();
+ uint64_t outBufferAge;
+ FrameEventHistoryDelta outTimestamps;
+ sp<android::Fence> fence;
+ producer->dequeueBuffer(&slot, &fence, width, height, format, usage, &outBufferAge,
+ &outTimestamps);
+ producer->detachBuffer(slot);
+ producer->detachNextBuffer(&buffer, &fence);
+ producer->cancelBuffer(slot, fence);
+
+ invokeQuery(producer);
+
+ ManageResourceHandle handle(&mFdp);
+ producer->setSidebandStream(handle.getStream());
+
+ producer->allocateBuffers(width, height, format, usage);
+ producer->allowAllocation(mFdp.ConsumeBool() /*allow*/);
+ producer->setSharedBufferMode(mFdp.ConsumeBool() /*sharedBufferMode*/);
+ producer->setAutoRefresh(mFdp.ConsumeBool() /*autoRefresh*/);
+ producer->setLegacyBufferDrop(mFdp.ConsumeBool() /*drop*/);
+ producer->setAutoPrerotation(mFdp.ConsumeBool() /*autoPrerotation*/);
+
+ producer->setGenerationNumber(mFdp.ConsumeIntegral<uint32_t>());
+ producer->setDequeueTimeout(mFdp.ConsumeIntegral<uint32_t>());
+ producer->disconnect(api);
+}
+
+void BufferQueueFuzzer::invokeAcquireBuffer(sp<BufferQueueConsumer> consumer) {
+ BufferItem item;
+ consumer->acquireBuffer(&item, mFdp.ConsumeIntegral<uint32_t>(),
+ mFdp.ConsumeIntegral<uint64_t>());
+}
+
+void BufferQueueFuzzer::invokeOccupancyTracker(sp<BufferQueueConsumer> consumer) {
+ String8 outResult;
+ String8 prefix((mFdp.ConsumeRandomLengthString(kMaxBytes)).c_str());
+ consumer->dumpState(prefix, &outResult);
+
+ std::vector<OccupancyTracker::Segment> outHistory;
+ consumer->getOccupancyHistory(mFdp.ConsumeBool() /*forceFlush*/, &outHistory);
+}
+
+void BufferQueueFuzzer::invokeBufferQueueConsumer() {
+ sp<BufferQueueCore> core(new BufferQueueCore());
+ sp<BufferQueueConsumer> consumer(new BufferQueueConsumer(core));
+ sp<android::IConsumerListener> listener;
+ consumer->consumerConnect(listener, mFdp.ConsumeBool() /*controlledByApp*/);
+ invokeAcquireBuffer(consumer);
+
+ int32_t slot = mFdp.ConsumeIntegral<int32_t>();
+ sp<GraphicBuffer> buffer =
+ new GraphicBuffer(mFdp.ConsumeIntegral<uint32_t>(), mFdp.ConsumeIntegral<uint32_t>(),
+ mFdp.ConsumeIntegral<int32_t>(), mFdp.ConsumeIntegral<uint32_t>(),
+ mFdp.ConsumeIntegral<uint64_t>());
+ consumer->attachBuffer(&slot, buffer);
+ consumer->detachBuffer(slot);
+
+ consumer->setDefaultBufferSize(mFdp.ConsumeIntegral<uint32_t>(),
+ mFdp.ConsumeIntegral<uint32_t>());
+ consumer->setMaxBufferCount(mFdp.ConsumeIntegral<int32_t>());
+ consumer->setMaxAcquiredBufferCount(mFdp.ConsumeIntegral<int32_t>());
+
+ String8 name((mFdp.ConsumeRandomLengthString(kMaxBytes)).c_str());
+ consumer->setConsumerName(name);
+ consumer->setDefaultBufferFormat(mFdp.ConsumeIntegral<int32_t>());
+ android_dataspace dataspace =
+ static_cast<android_dataspace>(mFdp.PickValueInArray(kDataspaces));
+ consumer->setDefaultBufferDataSpace(dataspace);
+
+ consumer->setTransformHint(mFdp.ConsumeIntegral<uint32_t>());
+ consumer->setConsumerUsageBits(mFdp.ConsumeIntegral<uint64_t>());
+ consumer->setConsumerIsProtected(mFdp.ConsumeBool() /*isProtected*/);
+ invokeOccupancyTracker(consumer);
+
+ sp<Fence> releaseFence = new Fence(memfd_create("fd", MFD_ALLOW_SEALING));
+ consumer->releaseBuffer(mFdp.ConsumeIntegral<int32_t>(), mFdp.ConsumeIntegral<uint64_t>(),
+ EGL_NO_DISPLAY, EGL_NO_SYNC_KHR, releaseFence);
+ consumer->consumerDisconnect();
+}
+
+void BufferQueueFuzzer::invokeTypes() {
+ HStatus hStatus;
+ int32_t status = mFdp.PickValueInArray(kError);
+ bool bufferNeedsReallocation = mFdp.ConsumeBool();
+ bool releaseAllBuffers = mFdp.ConsumeBool();
+ b2h(status, &hStatus, &bufferNeedsReallocation, &releaseAllBuffers);
+ h2b(hStatus, &status);
+
+ HConnectionType type;
+ int32_t apiConnection = mFdp.PickValueInArray(kAPIConnection);
+ b2h(apiConnection, &type);
+ h2b(type, &apiConnection);
+}
+
+void BufferQueueFuzzer::invokeH2BGraphicBufferV1() {
+ sp<V1_0::utils::H2BGraphicBufferProducer> producer(
+ new V1_0::utils::H2BGraphicBufferProducer(new FakeGraphicBufferProducerV1()));
+ const sp<android::IProducerListener> listener;
+ android::IGraphicBufferProducer::QueueBufferOutput output;
+ uint32_t api = mFdp.ConsumeIntegral<uint32_t>();
+ producer->connect(listener, api, mFdp.ConsumeBool() /*producerControlledByApp*/, &output);
+
+ sp<GraphicBuffer> buffer;
+ int32_t slot = mFdp.ConsumeIntegral<int32_t>();
+ producer->requestBuffer(slot, &buffer);
+ producer->setMaxDequeuedBufferCount(mFdp.ConsumeIntegral<int32_t>());
+ producer->setAsyncMode(mFdp.ConsumeBool());
+
+ android::IGraphicBufferProducer::QueueBufferInput input;
+ input.fence = new Fence(memfd_create("ffd", MFD_ALLOW_SEALING));
+ producer->attachBuffer(&slot, buffer);
+ producer->queueBuffer(slot, input, &output);
+
+ int32_t format = mFdp.ConsumeIntegral<int32_t>();
+ uint32_t width = mFdp.ConsumeIntegral<uint32_t>();
+ uint32_t height = mFdp.ConsumeIntegral<uint32_t>();
+ uint64_t usage = mFdp.ConsumeIntegral<uint64_t>();
+ uint64_t outBufferAge;
+ FrameEventHistoryDelta outTimestamps;
+ sp<android::Fence> fence;
+ producer->dequeueBuffer(&slot, &fence, width, height, format, usage, &outBufferAge,
+ &outTimestamps);
+ producer->detachBuffer(slot);
+ producer->cancelBuffer(slot, fence);
+
+ invokeQuery(producer);
+
+ ManageResourceHandle handle(&mFdp);
+ producer->setSidebandStream(handle.getStream());
+
+ producer->allocateBuffers(width, height, format, usage);
+ producer->allowAllocation(mFdp.ConsumeBool() /*allow*/);
+ producer->setSharedBufferMode(mFdp.ConsumeBool() /*sharedBufferMode*/);
+ producer->setAutoRefresh(mFdp.ConsumeBool() /*autoRefresh*/);
+
+ producer->setGenerationNumber(mFdp.ConsumeIntegral<uint32_t>());
+ producer->setDequeueTimeout(mFdp.ConsumeIntegral<uint32_t>());
+ producer->disconnect(api);
+}
+
+void BufferQueueFuzzer::invokeH2BGraphicBufferV2() {
+ sp<V2_0::utils::H2BGraphicBufferProducer> producer(
+ new V2_0::utils::H2BGraphicBufferProducer(new FakeGraphicBufferProducerV2()));
+ const sp<android::IProducerListener> listener;
+ android::IGraphicBufferProducer::QueueBufferOutput output;
+ uint32_t api = mFdp.ConsumeIntegral<uint32_t>();
+ producer->connect(listener, api, mFdp.ConsumeBool() /*producerControlledByApp*/, &output);
+
+ sp<GraphicBuffer> buffer;
+ int32_t slot = mFdp.ConsumeIntegral<int32_t>();
+ producer->requestBuffer(slot, &buffer);
+ producer->setMaxDequeuedBufferCount(mFdp.ConsumeIntegral<uint32_t>());
+ producer->setAsyncMode(mFdp.ConsumeBool());
+
+ android::IGraphicBufferProducer::QueueBufferInput input;
+ input.fence = new Fence(memfd_create("ffd", MFD_ALLOW_SEALING));
+ producer->attachBuffer(&slot, buffer);
+ producer->queueBuffer(slot, input, &output);
+
+ int32_t format = mFdp.ConsumeIntegral<int32_t>();
+ uint32_t width = mFdp.ConsumeIntegral<uint32_t>();
+ uint32_t height = mFdp.ConsumeIntegral<uint32_t>();
+ uint64_t usage = mFdp.ConsumeIntegral<uint64_t>();
+ uint64_t outBufferAge;
+ FrameEventHistoryDelta outTimestamps;
+ sp<android::Fence> fence;
+ producer->dequeueBuffer(&slot, &fence, width, height, format, usage, &outBufferAge,
+ &outTimestamps);
+ producer->detachBuffer(slot);
+ producer->cancelBuffer(slot, fence);
+
+ invokeQuery(producer);
+
+ ManageResourceHandle handle(&mFdp);
+ producer->setSidebandStream(handle.getStream());
+
+ producer->allocateBuffers(width, height, format, usage);
+ producer->allowAllocation(mFdp.ConsumeBool() /*allow*/);
+ producer->setSharedBufferMode(mFdp.ConsumeBool() /*sharedBufferMode*/);
+ producer->setAutoRefresh(mFdp.ConsumeBool() /*autoRefresh*/);
+
+ producer->setGenerationNumber(mFdp.ConsumeIntegral<uint32_t>());
+ producer->setDequeueTimeout(mFdp.ConsumeIntegral<uint32_t>());
+ producer->disconnect(api);
+}
+
+void BufferQueueFuzzer::process() {
+ invokeBlastBufferQueue();
+ invokeH2BGraphicBufferV1();
+ invokeH2BGraphicBufferV2();
+ invokeTypes();
+ invokeBufferQueueConsumer();
+ invokeBufferQueueProducer();
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ BufferQueueFuzzer bufferQueueFuzzer(data, size);
+ bufferQueueFuzzer.process();
+ return 0;
+}
diff --git a/libs/gui/fuzzer/libgui_consumer_fuzzer.cpp b/libs/gui/fuzzer/libgui_consumer_fuzzer.cpp
new file mode 100644
index 0000000000..24a046d3a9
--- /dev/null
+++ b/libs/gui/fuzzer/libgui_consumer_fuzzer.cpp
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <gui/BufferQueueConsumer.h>
+#include <gui/BufferQueueCore.h>
+#include <gui/BufferQueueProducer.h>
+#include <gui/GLConsumer.h>
+#include <libgui_fuzzer_utils.h>
+
+using namespace android;
+
+constexpr int32_t kMinBuffer = 0;
+constexpr int32_t kMaxBuffer = 100000;
+
+class ConsumerFuzzer {
+public:
+ ConsumerFuzzer(const uint8_t* data, size_t size) : mFdp(data, size){};
+ void process();
+
+private:
+ FuzzedDataProvider mFdp;
+};
+
+void ConsumerFuzzer::process() {
+ sp<BufferQueueCore> core(new BufferQueueCore());
+ sp<IGraphicBufferConsumer> consumer(new BufferQueueConsumer(core));
+
+ uint64_t maxBuffers = mFdp.ConsumeIntegralInRange<uint64_t>(kMinBuffer, kMaxBuffer);
+ sp<CpuConsumer> cpu(
+ new CpuConsumer(consumer, maxBuffers, mFdp.ConsumeBool() /*controlledByApp*/));
+ CpuConsumer::LockedBuffer lockBuffer;
+ cpu->lockNextBuffer(&lockBuffer);
+ cpu->unlockBuffer(lockBuffer);
+ cpu->abandon();
+
+ uint32_t tex = mFdp.ConsumeIntegral<uint32_t>();
+ sp<GLConsumer> glComsumer(new GLConsumer(consumer, tex, GLConsumer::TEXTURE_EXTERNAL,
+ mFdp.ConsumeBool() /*useFenceSync*/,
+ mFdp.ConsumeBool() /*isControlledByApp*/));
+ sp<Fence> releaseFence = new Fence(memfd_create("rfd", MFD_ALLOW_SEALING));
+ glComsumer->setReleaseFence(releaseFence);
+ glComsumer->updateTexImage();
+ glComsumer->releaseTexImage();
+
+ sp<GraphicBuffer> buffer =
+ new GraphicBuffer(mFdp.ConsumeIntegral<uint32_t>(), mFdp.ConsumeIntegral<uint32_t>(),
+ mFdp.ConsumeIntegral<int32_t>(), mFdp.ConsumeIntegral<uint32_t>(),
+ mFdp.ConsumeIntegral<uint64_t>());
+ float mtx[16];
+ glComsumer->getTransformMatrix(mtx);
+ glComsumer->computeTransformMatrix(mtx, buffer, getRect(&mFdp),
+ mFdp.ConsumeIntegral<uint32_t>(),
+ mFdp.ConsumeBool() /*filtering*/);
+ glComsumer->scaleDownCrop(getRect(&mFdp), mFdp.ConsumeIntegral<uint32_t>(),
+ mFdp.ConsumeIntegral<uint32_t>());
+
+ glComsumer->setDefaultBufferSize(mFdp.ConsumeIntegral<uint32_t>(),
+ mFdp.ConsumeIntegral<uint32_t>());
+ glComsumer->setFilteringEnabled(mFdp.ConsumeBool() /*enabled*/);
+
+ glComsumer->setConsumerUsageBits(mFdp.ConsumeIntegral<uint64_t>());
+ glComsumer->attachToContext(tex);
+ glComsumer->abandon();
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ ConsumerFuzzer consumerFuzzer(data, size);
+ consumerFuzzer.process();
+ return 0;
+}
diff --git a/libs/gui/fuzzer/libgui_displayEvent_fuzzer.cpp b/libs/gui/fuzzer/libgui_displayEvent_fuzzer.cpp
new file mode 100644
index 0000000000..6e4f074825
--- /dev/null
+++ b/libs/gui/fuzzer/libgui_displayEvent_fuzzer.cpp
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android/gui/ISurfaceComposer.h>
+
+#include <libgui_fuzzer_utils.h>
+
+using namespace android;
+
+constexpr gui::ISurfaceComposer::VsyncSource kVsyncSource[] = {
+ gui::ISurfaceComposer::VsyncSource::eVsyncSourceApp,
+ gui::ISurfaceComposer::VsyncSource::eVsyncSourceSurfaceFlinger,
+};
+
+constexpr gui::ISurfaceComposer::EventRegistration kEventRegistration[] = {
+ gui::ISurfaceComposer::EventRegistration::modeChanged,
+ gui::ISurfaceComposer::EventRegistration::frameRateOverride,
+};
+
+constexpr uint32_t kDisplayEvent[] = {
+ DisplayEventReceiver::DISPLAY_EVENT_NULL,
+ DisplayEventReceiver::DISPLAY_EVENT_VSYNC,
+ DisplayEventReceiver::DISPLAY_EVENT_HOTPLUG,
+ DisplayEventReceiver::DISPLAY_EVENT_MODE_CHANGE,
+ DisplayEventReceiver::DISPLAY_EVENT_FRAME_RATE_OVERRIDE,
+ DisplayEventReceiver::DISPLAY_EVENT_FRAME_RATE_OVERRIDE_FLUSH,
+};
+
+constexpr int32_t kEvents[] = {
+ Looper::EVENT_INPUT, Looper::EVENT_OUTPUT, Looper::EVENT_ERROR,
+ Looper::EVENT_HANGUP, Looper::EVENT_INVALID,
+};
+
+DisplayEventReceiver::Event buildDisplayEvent(FuzzedDataProvider* fdp, uint32_t type,
+ DisplayEventReceiver::Event event) {
+ switch (type) {
+ case DisplayEventReceiver::DISPLAY_EVENT_VSYNC: {
+ event.vsync.count = fdp->ConsumeIntegral<uint32_t>();
+ event.vsync.vsyncData.frameInterval = fdp->ConsumeIntegral<uint64_t>();
+ event.vsync.vsyncData.preferredFrameTimelineIndex = fdp->ConsumeIntegral<uint32_t>();
+ for (size_t idx = 0; idx < gui::VsyncEventData::kFrameTimelinesCapacity; ++idx) {
+ event.vsync.vsyncData.frameTimelines[idx].vsyncId = fdp->ConsumeIntegral<int64_t>();
+ event.vsync.vsyncData.frameTimelines[idx].deadlineTimestamp =
+ fdp->ConsumeIntegral<uint64_t>();
+ event.vsync.vsyncData.frameTimelines[idx].expectedPresentationTime =
+ fdp->ConsumeIntegral<uint64_t>();
+ }
+ break;
+
+ }
+ case DisplayEventReceiver::DISPLAY_EVENT_HOTPLUG: {
+ event.hotplug = DisplayEventReceiver::Event::Hotplug{fdp->ConsumeBool() /*connected*/};
+ break;
+ }
+ case DisplayEventReceiver::DISPLAY_EVENT_MODE_CHANGE: {
+ event.modeChange =
+ DisplayEventReceiver::Event::ModeChange{fdp->ConsumeIntegral<int32_t>(),
+ fdp->ConsumeIntegral<int64_t>()};
+ break;
+ }
+ case DisplayEventReceiver::DISPLAY_EVENT_FRAME_RATE_OVERRIDE:
+ case DisplayEventReceiver::DISPLAY_EVENT_FRAME_RATE_OVERRIDE_FLUSH: {
+ event.frameRateOverride =
+ DisplayEventReceiver::Event::FrameRateOverride{fdp->ConsumeIntegral<uint32_t>(),
+ fdp->ConsumeFloatingPoint<
+ float>()};
+ break;
+ }
+ }
+ return event;
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ FuzzedDataProvider fdp(data, size);
+ sp<Looper> looper;
+ sp<FakeDisplayEventDispatcher> dispatcher(
+ new FakeDisplayEventDispatcher(looper, fdp.PickValueInArray(kVsyncSource),
+ fdp.PickValueInArray(kEventRegistration)));
+
+ dispatcher->initialize();
+ DisplayEventReceiver::Event event;
+ uint32_t type = fdp.PickValueInArray(kDisplayEvent);
+ PhysicalDisplayId displayId;
+ event.header =
+ DisplayEventReceiver::Event::Header{type, displayId, fdp.ConsumeIntegral<int64_t>()};
+ event = buildDisplayEvent(&fdp, type, event);
+
+ dispatcher->injectEvent(event);
+ dispatcher->handleEvent(0, fdp.PickValueInArray(kEvents), nullptr);
+ return 0;
+}
diff --git a/libs/gui/fuzzer/libgui_fuzzer_utils.h b/libs/gui/fuzzer/libgui_fuzzer_utils.h
new file mode 100644
index 0000000000..4c7d0562af
--- /dev/null
+++ b/libs/gui/fuzzer/libgui_fuzzer_utils.h
@@ -0,0 +1,315 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <android/gui/BnRegionSamplingListener.h>
+#include <android/gui/BnSurfaceComposer.h>
+#include <android/gui/BnSurfaceComposerClient.h>
+#include <android/gui/IDisplayEventConnection.h>
+#include <android/gui/ISurfaceComposerClient.h>
+#include <fuzzer/FuzzedDataProvider.h>
+#include <gmock/gmock.h>
+#include <gui/BLASTBufferQueue.h>
+#include <gui/DisplayEventDispatcher.h>
+#include <gui/IGraphicBufferProducer.h>
+#include <gui/LayerDebugInfo.h>
+#include <gui/LayerState.h>
+#include <gui/bufferqueue/1.0/H2BGraphicBufferProducer.h>
+#include <gui/bufferqueue/2.0/H2BGraphicBufferProducer.h>
+#include <ui/fuzzer/FuzzableDataspaces.h>
+
+namespace android {
+
+constexpr uint32_t kOrientation[] = {
+ ui::Transform::ROT_0, ui::Transform::FLIP_H, ui::Transform::FLIP_V,
+ ui::Transform::ROT_90, ui::Transform::ROT_180, ui::Transform::ROT_270,
+};
+
+Rect getRect(FuzzedDataProvider* fdp) {
+ const int32_t left = fdp->ConsumeIntegral<int32_t>();
+ const int32_t top = fdp->ConsumeIntegral<int32_t>();
+ const int32_t right = fdp->ConsumeIntegral<int32_t>();
+ const int32_t bottom = fdp->ConsumeIntegral<int32_t>();
+ return Rect(left, top, right, bottom);
+}
+
+gui::DisplayBrightness getBrightness(FuzzedDataProvider* fdp) {
+ static constexpr float kMinBrightness = 0;
+ static constexpr float kMaxBrightness = 1;
+ gui::DisplayBrightness brightness;
+ brightness.sdrWhitePoint =
+ fdp->ConsumeFloatingPointInRange<float>(kMinBrightness, kMaxBrightness);
+ brightness.sdrWhitePointNits =
+ fdp->ConsumeFloatingPointInRange<float>(kMinBrightness, kMaxBrightness);
+ brightness.displayBrightness =
+ fdp->ConsumeFloatingPointInRange<float>(kMinBrightness, kMaxBrightness);
+ brightness.displayBrightnessNits =
+ fdp->ConsumeFloatingPointInRange<float>(kMinBrightness, kMaxBrightness);
+ return brightness;
+}
+
+class FakeBnSurfaceComposer : public gui::BnSurfaceComposer {
+public:
+ MOCK_METHOD(binder::Status, bootFinished, (), (override));
+ MOCK_METHOD(binder::Status, createDisplayEventConnection,
+ (gui::ISurfaceComposer::VsyncSource, gui::ISurfaceComposer::EventRegistration,
+ const sp<IBinder>& /*layerHandle*/, sp<gui::IDisplayEventConnection>*),
+ (override));
+ MOCK_METHOD(binder::Status, createConnection, (sp<gui::ISurfaceComposerClient>*), (override));
+ MOCK_METHOD(binder::Status, createDisplay, (const std::string&, bool, float, sp<IBinder>*),
+ (override));
+ MOCK_METHOD(binder::Status, destroyDisplay, (const sp<IBinder>&), (override));
+ MOCK_METHOD(binder::Status, getPhysicalDisplayIds, (std::vector<int64_t>*), (override));
+ MOCK_METHOD(binder::Status, getPhysicalDisplayToken, (int64_t, sp<IBinder>*), (override));
+ MOCK_METHOD(binder::Status, setPowerMode, (const sp<IBinder>&, int), (override));
+ MOCK_METHOD(binder::Status, getSupportedFrameTimestamps, (std::vector<FrameEvent>*),
+ (override));
+ MOCK_METHOD(binder::Status, getDisplayStats, (const sp<IBinder>&, gui::DisplayStatInfo*),
+ (override));
+ MOCK_METHOD(binder::Status, getDisplayState, (const sp<IBinder>&, gui::DisplayState*),
+ (override));
+ MOCK_METHOD(binder::Status, getStaticDisplayInfo, (int64_t, gui::StaticDisplayInfo*),
+ (override));
+ MOCK_METHOD(binder::Status, getDynamicDisplayInfoFromId, (int64_t, gui::DynamicDisplayInfo*),
+ (override));
+ MOCK_METHOD(binder::Status, getDynamicDisplayInfoFromToken,
+ (const sp<IBinder>&, gui::DynamicDisplayInfo*), (override));
+ MOCK_METHOD(binder::Status, getDisplayNativePrimaries,
+ (const sp<IBinder>&, gui::DisplayPrimaries*), (override));
+ MOCK_METHOD(binder::Status, setActiveColorMode, (const sp<IBinder>&, int), (override));
+ MOCK_METHOD(binder::Status, setBootDisplayMode, (const sp<IBinder>&, int), (override));
+ MOCK_METHOD(binder::Status, clearBootDisplayMode, (const sp<IBinder>&), (override));
+ MOCK_METHOD(binder::Status, getBootDisplayModeSupport, (bool*), (override));
+ MOCK_METHOD(binder::Status, getHdrConversionCapabilities,
+ (std::vector<gui::HdrConversionCapability>*), (override));
+ MOCK_METHOD(binder::Status, setHdrConversionStrategy,
+ (const gui::HdrConversionStrategy&, int32_t*), (override));
+ MOCK_METHOD(binder::Status, getHdrOutputConversionSupport, (bool*), (override));
+ MOCK_METHOD(binder::Status, setAutoLowLatencyMode, (const sp<IBinder>&, bool), (override));
+ MOCK_METHOD(binder::Status, setGameContentType, (const sp<IBinder>&, bool), (override));
+ MOCK_METHOD(binder::Status, captureDisplay,
+ (const DisplayCaptureArgs&, const sp<IScreenCaptureListener>&), (override));
+ MOCK_METHOD(binder::Status, captureDisplayById, (int64_t, const sp<IScreenCaptureListener>&),
+ (override));
+ MOCK_METHOD(binder::Status, captureLayers,
+ (const LayerCaptureArgs&, const sp<IScreenCaptureListener>&), (override));
+ MOCK_METHOD(binder::Status, clearAnimationFrameStats, (), (override));
+ MOCK_METHOD(binder::Status, getAnimationFrameStats, (gui::FrameStats*), (override));
+ MOCK_METHOD(binder::Status, overrideHdrTypes, (const sp<IBinder>&, const std::vector<int32_t>&),
+ (override));
+ MOCK_METHOD(binder::Status, onPullAtom, (int32_t, gui::PullAtomData*), (override));
+ MOCK_METHOD(binder::Status, getLayerDebugInfo, (std::vector<gui::LayerDebugInfo>*), (override));
+ MOCK_METHOD(binder::Status, getColorManagement, (bool*), (override));
+ MOCK_METHOD(binder::Status, getCompositionPreference, (gui::CompositionPreference*),
+ (override));
+ MOCK_METHOD(binder::Status, getDisplayedContentSamplingAttributes,
+ (const sp<IBinder>&, gui::ContentSamplingAttributes*), (override));
+ MOCK_METHOD(binder::Status, setDisplayContentSamplingEnabled,
+ (const sp<IBinder>&, bool, int8_t, int64_t), (override));
+ MOCK_METHOD(binder::Status, getDisplayedContentSample,
+ (const sp<IBinder>&, int64_t, int64_t, gui::DisplayedFrameStats*), (override));
+ MOCK_METHOD(binder::Status, getProtectedContentSupport, (bool*), (override));
+ MOCK_METHOD(binder::Status, isWideColorDisplay, (const sp<IBinder>&, bool*), (override));
+ MOCK_METHOD(binder::Status, addRegionSamplingListener,
+ (const gui::ARect&, const sp<IBinder>&, const sp<gui::IRegionSamplingListener>&),
+ (override));
+ MOCK_METHOD(binder::Status, removeRegionSamplingListener,
+ (const sp<gui::IRegionSamplingListener>&), (override));
+ MOCK_METHOD(binder::Status, addFpsListener, (int32_t, const sp<gui::IFpsListener>&),
+ (override));
+ MOCK_METHOD(binder::Status, removeFpsListener, (const sp<gui::IFpsListener>&), (override));
+ MOCK_METHOD(binder::Status, addTunnelModeEnabledListener,
+ (const sp<gui::ITunnelModeEnabledListener>&), (override));
+ MOCK_METHOD(binder::Status, removeTunnelModeEnabledListener,
+ (const sp<gui::ITunnelModeEnabledListener>&), (override));
+ MOCK_METHOD(binder::Status, setDesiredDisplayModeSpecs,
+ (const sp<IBinder>&, const gui::DisplayModeSpecs&), (override));
+ MOCK_METHOD(binder::Status, getDesiredDisplayModeSpecs,
+ (const sp<IBinder>&, gui::DisplayModeSpecs*), (override));
+ MOCK_METHOD(binder::Status, getDisplayBrightnessSupport, (const sp<IBinder>&, bool*),
+ (override));
+ MOCK_METHOD(binder::Status, setDisplayBrightness,
+ (const sp<IBinder>&, const gui::DisplayBrightness&), (override));
+ MOCK_METHOD(binder::Status, addHdrLayerInfoListener,
+ (const sp<IBinder>&, const sp<gui::IHdrLayerInfoListener>&), (override));
+ MOCK_METHOD(binder::Status, removeHdrLayerInfoListener,
+ (const sp<IBinder>&, const sp<gui::IHdrLayerInfoListener>&), (override));
+ MOCK_METHOD(binder::Status, notifyPowerBoost, (int), (override));
+ MOCK_METHOD(binder::Status, setGlobalShadowSettings,
+ (const gui::Color&, const gui::Color&, float, float, float), (override));
+ MOCK_METHOD(binder::Status, getDisplayDecorationSupport,
+ (const sp<IBinder>&, std::optional<gui::DisplayDecorationSupport>*), (override));
+ MOCK_METHOD(binder::Status, setOverrideFrameRate, (int32_t, float), (override));
+ MOCK_METHOD(binder::Status, getGpuContextPriority, (int32_t*), (override));
+ MOCK_METHOD(binder::Status, getMaxAcquiredBufferCount, (int32_t*), (override));
+ MOCK_METHOD(binder::Status, addWindowInfosListener,
+ (const sp<gui::IWindowInfosListener>&, gui::WindowInfosListenerInfo*), (override));
+ MOCK_METHOD(binder::Status, removeWindowInfosListener, (const sp<gui::IWindowInfosListener>&),
+ (override));
+ MOCK_METHOD(binder::Status, getOverlaySupport, (gui::OverlayProperties*), (override));
+};
+
+class FakeBnSurfaceComposerClient : public gui::BnSurfaceComposerClient {
+public:
+ MOCK_METHOD(binder::Status, createSurface,
+ (const std::string& name, int32_t flags, const sp<IBinder>& parent,
+ const gui::LayerMetadata& metadata, gui::CreateSurfaceResult* outResult),
+ (override));
+
+ MOCK_METHOD(binder::Status, clearLayerFrameStats, (const sp<IBinder>& handle), (override));
+
+ MOCK_METHOD(binder::Status, getLayerFrameStats,
+ (const sp<IBinder>& handle, gui::FrameStats* outStats), (override));
+
+ MOCK_METHOD(binder::Status, mirrorSurface,
+ (const sp<IBinder>& mirrorFromHandle, gui::CreateSurfaceResult* outResult),
+ (override));
+
+ MOCK_METHOD(binder::Status, mirrorDisplay,
+ (int64_t displayId, gui::CreateSurfaceResult* outResult), (override));
+};
+
+class FakeDisplayEventDispatcher : public DisplayEventDispatcher {
+public:
+ FakeDisplayEventDispatcher(const sp<Looper>& looper,
+ gui::ISurfaceComposer::VsyncSource vsyncSource,
+ gui::ISurfaceComposer::EventRegistration eventRegistration)
+ : DisplayEventDispatcher(looper, vsyncSource, eventRegistration){};
+
+ MOCK_METHOD4(dispatchVsync, void(nsecs_t, PhysicalDisplayId, uint32_t, VsyncEventData));
+ MOCK_METHOD3(dispatchHotplug, void(nsecs_t, PhysicalDisplayId, bool));
+ MOCK_METHOD4(dispatchModeChanged, void(nsecs_t, PhysicalDisplayId, int32_t, nsecs_t));
+ MOCK_METHOD2(dispatchNullEvent, void(nsecs_t, PhysicalDisplayId));
+ MOCK_METHOD3(dispatchFrameRateOverrides,
+ void(nsecs_t, PhysicalDisplayId, std::vector<FrameRateOverride>));
+};
+
+} // namespace android
+
+namespace android::hardware {
+
+namespace graphics::bufferqueue::V1_0::utils {
+
+class FakeGraphicBufferProducerV1 : public HGraphicBufferProducer {
+public:
+ FakeGraphicBufferProducerV1() {
+ ON_CALL(*this, setMaxDequeuedBufferCount).WillByDefault([]() { return 0; });
+ ON_CALL(*this, setAsyncMode).WillByDefault([]() { return 0; });
+ ON_CALL(*this, detachBuffer).WillByDefault([]() { return 0; });
+ ON_CALL(*this, cancelBuffer).WillByDefault([]() { return 0; });
+ ON_CALL(*this, disconnect).WillByDefault([]() { return 0; });
+ ON_CALL(*this, setSidebandStream).WillByDefault([]() { return 0; });
+ ON_CALL(*this, allowAllocation).WillByDefault([]() { return 0; });
+ ON_CALL(*this, setGenerationNumber).WillByDefault([]() { return 0; });
+ ON_CALL(*this, setSharedBufferMode).WillByDefault([]() { return 0; });
+ ON_CALL(*this, setAutoRefresh).WillByDefault([]() { return 0; });
+ ON_CALL(*this, setDequeueTimeout).WillByDefault([]() { return 0; });
+ ON_CALL(*this, setLegacyBufferDrop).WillByDefault([]() { return 0; });
+ };
+ MOCK_METHOD2(requestBuffer, Return<void>(int, requestBuffer_cb));
+ MOCK_METHOD1(setMaxDequeuedBufferCount, Return<int32_t>(int32_t));
+ MOCK_METHOD1(setAsyncMode, Return<int32_t>(bool));
+ MOCK_METHOD6(dequeueBuffer,
+ Return<void>(uint32_t, uint32_t, graphics::common::V1_0::PixelFormat, uint32_t,
+ bool, dequeueBuffer_cb));
+ MOCK_METHOD1(detachBuffer, Return<int32_t>(int));
+ MOCK_METHOD1(detachNextBuffer, Return<void>(detachNextBuffer_cb));
+ MOCK_METHOD2(attachBuffer, Return<void>(const media::V1_0::AnwBuffer&, attachBuffer_cb));
+ MOCK_METHOD3(
+ queueBuffer,
+ Return<void>(
+ int,
+ const graphics::bufferqueue::V1_0::IGraphicBufferProducer::QueueBufferInput&,
+ queueBuffer_cb));
+ MOCK_METHOD2(cancelBuffer, Return<int32_t>(int, const hidl_handle&));
+ MOCK_METHOD2(query, Return<void>(int32_t, query_cb));
+ MOCK_METHOD4(connect,
+ Return<void>(const sp<graphics::bufferqueue::V1_0::IProducerListener>&, int32_t,
+ bool, connect_cb));
+ MOCK_METHOD2(disconnect,
+ Return<int32_t>(
+ int, graphics::bufferqueue::V1_0::IGraphicBufferProducer::DisconnectMode));
+ MOCK_METHOD1(setSidebandStream, Return<int32_t>(const hidl_handle&));
+ MOCK_METHOD4(allocateBuffers,
+ Return<void>(uint32_t, uint32_t, graphics::common::V1_0::PixelFormat, uint32_t));
+ MOCK_METHOD1(allowAllocation, Return<int32_t>(bool));
+ MOCK_METHOD1(setGenerationNumber, Return<int32_t>(uint32_t));
+ MOCK_METHOD1(getConsumerName, Return<void>(getConsumerName_cb));
+ MOCK_METHOD1(setSharedBufferMode, Return<int32_t>(bool));
+ MOCK_METHOD1(setAutoRefresh, Return<int32_t>(bool));
+ MOCK_METHOD1(setDequeueTimeout, Return<int32_t>(nsecs_t));
+ MOCK_METHOD1(setLegacyBufferDrop, Return<int32_t>(bool));
+ MOCK_METHOD1(getLastQueuedBuffer, Return<void>(getLastQueuedBuffer_cb));
+ MOCK_METHOD1(getFrameTimestamps, Return<void>(getFrameTimestamps_cb));
+ MOCK_METHOD1(getUniqueId, Return<void>(getUniqueId_cb));
+};
+
+}; // namespace graphics::bufferqueue::V1_0::utils
+
+namespace graphics::bufferqueue::V2_0::utils {
+
+class FakeGraphicBufferProducerV2 : public HGraphicBufferProducer {
+public:
+ FakeGraphicBufferProducerV2() {
+ ON_CALL(*this, setMaxDequeuedBufferCount).WillByDefault([]() { return Status::OK; });
+ ON_CALL(*this, setAsyncMode).WillByDefault([]() { return Status::OK; });
+ ON_CALL(*this, detachBuffer).WillByDefault([]() { return Status::OK; });
+ ON_CALL(*this, cancelBuffer).WillByDefault([]() { return Status::OK; });
+ ON_CALL(*this, disconnect).WillByDefault([]() { return Status::OK; });
+ ON_CALL(*this, allocateBuffers).WillByDefault([]() { return Status::OK; });
+ ON_CALL(*this, allowAllocation).WillByDefault([]() { return Status::OK; });
+ ON_CALL(*this, setGenerationNumber).WillByDefault([]() { return Status::OK; });
+ ON_CALL(*this, setDequeueTimeout).WillByDefault([]() { return Status::OK; });
+ ON_CALL(*this, getUniqueId).WillByDefault([]() { return 0; });
+ };
+ MOCK_METHOD2(requestBuffer, Return<void>(int, requestBuffer_cb));
+ MOCK_METHOD1(setMaxDequeuedBufferCount, Return<graphics::bufferqueue::V2_0::Status>(int));
+ MOCK_METHOD1(setAsyncMode, Return<graphics::bufferqueue::V2_0::Status>(bool));
+ MOCK_METHOD2(
+ dequeueBuffer,
+ Return<void>(
+ const graphics::bufferqueue::V2_0::IGraphicBufferProducer::DequeueBufferInput&,
+ dequeueBuffer_cb));
+ MOCK_METHOD1(detachBuffer, Return<graphics::bufferqueue::V2_0::Status>(int));
+ MOCK_METHOD1(detachNextBuffer, Return<void>(detachNextBuffer_cb));
+ MOCK_METHOD3(attachBuffer,
+ Return<void>(const graphics::common::V1_2::HardwareBuffer&, uint32_t,
+ attachBuffer_cb));
+ MOCK_METHOD3(
+ queueBuffer,
+ Return<void>(
+ int,
+ const graphics::bufferqueue::V2_0::IGraphicBufferProducer::QueueBufferInput&,
+ queueBuffer_cb));
+ MOCK_METHOD2(cancelBuffer,
+ Return<graphics::bufferqueue::V2_0::Status>(int, const hidl_handle&));
+ MOCK_METHOD2(query, Return<void>(int32_t, query_cb));
+ MOCK_METHOD4(connect,
+ Return<void>(const sp<graphics::bufferqueue::V2_0::IProducerListener>&,
+ graphics::bufferqueue::V2_0::ConnectionType, bool, connect_cb));
+ MOCK_METHOD1(disconnect,
+ Return<graphics::bufferqueue::V2_0::Status>(
+ graphics::bufferqueue::V2_0::ConnectionType));
+ MOCK_METHOD4(allocateBuffers,
+ Return<graphics::bufferqueue::V2_0::Status>(uint32_t, uint32_t, uint32_t,
+ uint64_t));
+ MOCK_METHOD1(allowAllocation, Return<graphics::bufferqueue::V2_0::Status>(bool));
+ MOCK_METHOD1(setGenerationNumber, Return<graphics::bufferqueue::V2_0::Status>(uint32_t));
+ MOCK_METHOD1(getConsumerName, Return<void>(getConsumerName_cb));
+ MOCK_METHOD1(setDequeueTimeout, Return<graphics::bufferqueue::V2_0::Status>(int64_t));
+ MOCK_METHOD0(getUniqueId, Return<uint64_t>());
+};
+
+}; // namespace graphics::bufferqueue::V2_0::utils
+}; // namespace android::hardware
diff --git a/libs/gui/fuzzer/libgui_parcelable_fuzzer.cpp b/libs/gui/fuzzer/libgui_parcelable_fuzzer.cpp
new file mode 100644
index 0000000000..9f0f6cac19
--- /dev/null
+++ b/libs/gui/fuzzer/libgui_parcelable_fuzzer.cpp
@@ -0,0 +1,175 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <gui/BufferQueueConsumer.h>
+#include <gui/BufferQueueCore.h>
+#include <gui/BufferQueueProducer.h>
+#include <gui/LayerMetadata.h>
+#include <gui/OccupancyTracker.h>
+#include <gui/StreamSplitter.h>
+#include <gui/Surface.h>
+#include <gui/SurfaceControl.h>
+#include <gui/view/Surface.h>
+#include <libgui_fuzzer_utils.h>
+#include "android/view/LayerMetadataKey.h"
+
+using namespace android;
+
+constexpr int32_t kMaxBytes = 256;
+constexpr int32_t kMatrixSize = 4;
+constexpr int32_t kLayerMetadataKeyCount = 8;
+
+constexpr uint32_t kMetadataKey[] = {
+ (uint32_t)view::LayerMetadataKey::METADATA_OWNER_UID,
+ (uint32_t)view::LayerMetadataKey::METADATA_WINDOW_TYPE,
+ (uint32_t)view::LayerMetadataKey::METADATA_TASK_ID,
+ (uint32_t)view::LayerMetadataKey::METADATA_MOUSE_CURSOR,
+ (uint32_t)view::LayerMetadataKey::METADATA_ACCESSIBILITY_ID,
+ (uint32_t)view::LayerMetadataKey::METADATA_OWNER_PID,
+ (uint32_t)view::LayerMetadataKey::METADATA_DEQUEUE_TIME,
+ (uint32_t)view::LayerMetadataKey::METADATA_GAME_MODE,
+};
+
+class ParcelableFuzzer {
+public:
+ ParcelableFuzzer(const uint8_t* data, size_t size) : mFdp(data, size){};
+ void process();
+
+private:
+ void invokeStreamSplitter();
+ void invokeOccupancyTracker();
+ void invokeLayerDebugInfo();
+ void invokeLayerMetadata();
+ void invokeViewSurface();
+
+ FuzzedDataProvider mFdp;
+};
+
+void ParcelableFuzzer::invokeViewSurface() {
+ view::Surface surface;
+ surface.name = String16((mFdp.ConsumeRandomLengthString(kMaxBytes)).c_str());
+ Parcel parcel;
+ surface.writeToParcel(&parcel);
+ parcel.setDataPosition(0);
+ surface.readFromParcel(&parcel);
+ bool nameAlreadyWritten = mFdp.ConsumeBool();
+ surface.writeToParcel(&parcel, nameAlreadyWritten);
+ parcel.setDataPosition(0);
+ surface.readFromParcel(&parcel, mFdp.ConsumeBool());
+}
+
+void ParcelableFuzzer::invokeLayerMetadata() {
+ std::unordered_map<uint32_t, std::vector<uint8_t>> map;
+ for (size_t idx = 0; idx < kLayerMetadataKeyCount; ++idx) {
+ std::vector<uint8_t> data;
+ for (size_t idx1 = 0; idx1 < mFdp.ConsumeIntegral<uint32_t>(); ++idx1) {
+ data.push_back(mFdp.ConsumeIntegral<uint8_t>());
+ }
+ map[kMetadataKey[idx]] = data;
+ }
+ LayerMetadata metadata(map);
+ uint32_t key = mFdp.PickValueInArray(kMetadataKey);
+ metadata.setInt32(key, mFdp.ConsumeIntegral<int32_t>());
+ metadata.itemToString(key, (mFdp.ConsumeRandomLengthString(kMaxBytes)).c_str());
+
+ Parcel parcel;
+ metadata.writeToParcel(&parcel);
+ parcel.setDataPosition(0);
+ metadata.readFromParcel(&parcel);
+}
+
+void ParcelableFuzzer::invokeLayerDebugInfo() {
+ gui::LayerDebugInfo info;
+ info.mName = mFdp.ConsumeRandomLengthString(kMaxBytes);
+ info.mParentName = mFdp.ConsumeRandomLengthString(kMaxBytes);
+ info.mType = mFdp.ConsumeRandomLengthString(kMaxBytes);
+ info.mLayerStack = mFdp.ConsumeIntegral<uint32_t>();
+ info.mX = mFdp.ConsumeFloatingPoint<float>();
+ info.mY = mFdp.ConsumeFloatingPoint<float>();
+ info.mZ = mFdp.ConsumeIntegral<uint32_t>();
+ info.mWidth = mFdp.ConsumeIntegral<int32_t>();
+ info.mHeight = mFdp.ConsumeIntegral<int32_t>();
+ info.mActiveBufferWidth = mFdp.ConsumeIntegral<int32_t>();
+ info.mActiveBufferHeight = mFdp.ConsumeIntegral<int32_t>();
+ info.mActiveBufferStride = mFdp.ConsumeIntegral<int32_t>();
+ info.mActiveBufferFormat = mFdp.ConsumeIntegral<int32_t>();
+ info.mNumQueuedFrames = mFdp.ConsumeIntegral<int32_t>();
+
+ info.mFlags = mFdp.ConsumeIntegral<uint32_t>();
+ info.mPixelFormat = mFdp.ConsumeIntegral<int32_t>();
+ info.mTransparentRegion = Region(getRect(&mFdp));
+ info.mVisibleRegion = Region(getRect(&mFdp));
+ info.mSurfaceDamageRegion = Region(getRect(&mFdp));
+ info.mCrop = getRect(&mFdp);
+ info.mDataSpace = static_cast<android_dataspace>(mFdp.PickValueInArray(kDataspaces));
+ info.mColor = half4(mFdp.ConsumeFloatingPoint<float>(), mFdp.ConsumeFloatingPoint<float>(),
+ mFdp.ConsumeFloatingPoint<float>(), mFdp.ConsumeFloatingPoint<float>());
+ for (size_t idx = 0; idx < kMatrixSize; ++idx) {
+ info.mMatrix[idx / 2][idx % 2] = mFdp.ConsumeFloatingPoint<float>();
+ }
+ info.mIsOpaque = mFdp.ConsumeBool();
+ info.mContentDirty = mFdp.ConsumeBool();
+ info.mStretchEffect.width = mFdp.ConsumeFloatingPoint<float>();
+ info.mStretchEffect.height = mFdp.ConsumeFloatingPoint<float>();
+ info.mStretchEffect.vectorX = mFdp.ConsumeFloatingPoint<float>();
+ info.mStretchEffect.vectorY = mFdp.ConsumeFloatingPoint<float>();
+ info.mStretchEffect.maxAmountX = mFdp.ConsumeFloatingPoint<float>();
+ info.mStretchEffect.maxAmountY = mFdp.ConsumeFloatingPoint<float>();
+ info.mStretchEffect.mappedChildBounds =
+ FloatRect(mFdp.ConsumeFloatingPoint<float>(), mFdp.ConsumeFloatingPoint<float>(),
+ mFdp.ConsumeFloatingPoint<float>(), mFdp.ConsumeFloatingPoint<float>());
+
+ Parcel parcel;
+ info.writeToParcel(&parcel);
+ parcel.setDataPosition(0);
+ info.readFromParcel(&parcel);
+}
+
+void ParcelableFuzzer::invokeOccupancyTracker() {
+ nsecs_t totalTime = mFdp.ConsumeIntegral<uint32_t>();
+ size_t numFrames = mFdp.ConsumeIntegral<size_t>();
+ float occupancyAverage = mFdp.ConsumeFloatingPoint<float>();
+ OccupancyTracker::Segment segment(totalTime, numFrames, occupancyAverage,
+ mFdp.ConsumeBool() /*usedThirdBuffer*/);
+ Parcel parcel;
+ segment.writeToParcel(&parcel);
+ parcel.setDataPosition(0);
+ segment.readFromParcel(&parcel);
+}
+
+void ParcelableFuzzer::invokeStreamSplitter() {
+ sp<IGraphicBufferProducer> producer;
+ sp<IGraphicBufferConsumer> consumer;
+ BufferQueue::createBufferQueue(&producer, &consumer);
+ sp<StreamSplitter> splitter;
+ StreamSplitter::createSplitter(consumer, &splitter);
+ splitter->addOutput(producer);
+ std::string name = mFdp.ConsumeRandomLengthString(kMaxBytes);
+ splitter->setName(String8(name.c_str()));
+}
+
+void ParcelableFuzzer::process() {
+ invokeStreamSplitter();
+ invokeOccupancyTracker();
+ invokeLayerDebugInfo();
+ invokeLayerMetadata();
+ invokeViewSurface();
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ ParcelableFuzzer libGuiFuzzer(data, size);
+ libGuiFuzzer.process();
+ return 0;
+}
diff --git a/libs/gui/fuzzer/libgui_surfaceComposerClient_fuzzer.cpp b/libs/gui/fuzzer/libgui_surfaceComposerClient_fuzzer.cpp
new file mode 100644
index 0000000000..57720dd513
--- /dev/null
+++ b/libs/gui/fuzzer/libgui_surfaceComposerClient_fuzzer.cpp
@@ -0,0 +1,327 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <android/hardware/power/Boost.h>
+#include <fuzzbinder/libbinder_driver.h>
+#include <gui/Surface.h>
+#include <gui/SurfaceComposerClient.h>
+#include <libgui_fuzzer_utils.h>
+#include "android-base/stringprintf.h"
+
+using namespace android;
+
+constexpr int32_t kRandomStringMaxBytes = 256;
+
+constexpr ui::ColorMode kColormodes[] = {ui::ColorMode::NATIVE,
+ ui::ColorMode::STANDARD_BT601_625,
+ ui::ColorMode::STANDARD_BT601_625_UNADJUSTED,
+ ui::ColorMode::STANDARD_BT601_525,
+ ui::ColorMode::STANDARD_BT601_525_UNADJUSTED,
+ ui::ColorMode::STANDARD_BT709,
+ ui::ColorMode::DCI_P3,
+ ui::ColorMode::SRGB,
+ ui::ColorMode::ADOBE_RGB,
+ ui::ColorMode::DISPLAY_P3,
+ ui::ColorMode::BT2020,
+ ui::ColorMode::BT2100_PQ,
+ ui::ColorMode::BT2100_HLG,
+ ui::ColorMode::DISPLAY_BT2020};
+
+constexpr hardware::power::Boost kBoost[] = {
+ hardware::power::Boost::INTERACTION, hardware::power::Boost::DISPLAY_UPDATE_IMMINENT,
+ hardware::power::Boost::ML_ACC, hardware::power::Boost::AUDIO_LAUNCH,
+ hardware::power::Boost::CAMERA_LAUNCH, hardware::power::Boost::CAMERA_SHOT,
+};
+
+constexpr gui::TouchOcclusionMode kMode[] = {
+ gui::TouchOcclusionMode::BLOCK_UNTRUSTED,
+ gui::TouchOcclusionMode::USE_OPACITY,
+ gui::TouchOcclusionMode::ALLOW,
+};
+
+constexpr gui::WindowInfo::Flag kFlags[] = {
+ gui::WindowInfo::Flag::ALLOW_LOCK_WHILE_SCREEN_ON,
+ gui::WindowInfo::Flag::DIM_BEHIND,
+ gui::WindowInfo::Flag::BLUR_BEHIND,
+ gui::WindowInfo::Flag::NOT_FOCUSABLE,
+ gui::WindowInfo::Flag::NOT_TOUCHABLE,
+ gui::WindowInfo::Flag::NOT_TOUCH_MODAL,
+ gui::WindowInfo::Flag::TOUCHABLE_WHEN_WAKING,
+ gui::WindowInfo::Flag::KEEP_SCREEN_ON,
+ gui::WindowInfo::Flag::LAYOUT_IN_SCREEN,
+ gui::WindowInfo::Flag::LAYOUT_NO_LIMITS,
+ gui::WindowInfo::Flag::FULLSCREEN,
+ gui::WindowInfo::Flag::FORCE_NOT_FULLSCREEN,
+ gui::WindowInfo::Flag::DITHER,
+ gui::WindowInfo::Flag::SECURE,
+ gui::WindowInfo::Flag::SCALED,
+ gui::WindowInfo::Flag::IGNORE_CHEEK_PRESSES,
+ gui::WindowInfo::Flag::LAYOUT_INSET_DECOR,
+ gui::WindowInfo::Flag::ALT_FOCUSABLE_IM,
+ gui::WindowInfo::Flag::WATCH_OUTSIDE_TOUCH,
+ gui::WindowInfo::Flag::SHOW_WHEN_LOCKED,
+ gui::WindowInfo::Flag::SHOW_WALLPAPER,
+ gui::WindowInfo::Flag::TURN_SCREEN_ON,
+ gui::WindowInfo::Flag::DISMISS_KEYGUARD,
+ gui::WindowInfo::Flag::SPLIT_TOUCH,
+ gui::WindowInfo::Flag::HARDWARE_ACCELERATED,
+ gui::WindowInfo::Flag::LAYOUT_IN_OVERSCAN,
+ gui::WindowInfo::Flag::TRANSLUCENT_STATUS,
+ gui::WindowInfo::Flag::TRANSLUCENT_NAVIGATION,
+ gui::WindowInfo::Flag::LOCAL_FOCUS_MODE,
+ gui::WindowInfo::Flag::SLIPPERY,
+ gui::WindowInfo::Flag::LAYOUT_ATTACHED_IN_DECOR,
+ gui::WindowInfo::Flag::DRAWS_SYSTEM_BAR_BACKGROUNDS,
+};
+
+constexpr gui::WindowInfo::Type kType[] = {
+ gui::WindowInfo::Type::UNKNOWN,
+ gui::WindowInfo::Type::FIRST_APPLICATION_WINDOW,
+ gui::WindowInfo::Type::BASE_APPLICATION,
+ gui::WindowInfo::Type::APPLICATION,
+ gui::WindowInfo::Type::APPLICATION_STARTING,
+ gui::WindowInfo::Type::LAST_APPLICATION_WINDOW,
+ gui::WindowInfo::Type::FIRST_SUB_WINDOW,
+ gui::WindowInfo::Type::APPLICATION_PANEL,
+ gui::WindowInfo::Type::APPLICATION_MEDIA,
+ gui::WindowInfo::Type::APPLICATION_SUB_PANEL,
+ gui::WindowInfo::Type::APPLICATION_ATTACHED_DIALOG,
+ gui::WindowInfo::Type::APPLICATION_MEDIA_OVERLAY,
+};
+
+constexpr gui::WindowInfo::InputConfig kFeatures[] = {
+ gui::WindowInfo::InputConfig::NO_INPUT_CHANNEL,
+ gui::WindowInfo::InputConfig::DISABLE_USER_ACTIVITY,
+ gui::WindowInfo::InputConfig::DROP_INPUT,
+ gui::WindowInfo::InputConfig::DROP_INPUT_IF_OBSCURED,
+ gui::WindowInfo::InputConfig::SPY,
+ gui::WindowInfo::InputConfig::INTERCEPTS_STYLUS,
+};
+
+class SurfaceComposerClientFuzzer {
+public:
+ SurfaceComposerClientFuzzer(const uint8_t* data, size_t size) : mFdp(data, size){};
+ void process();
+
+private:
+ void invokeSurfaceComposerClient();
+ void invokeSurfaceComposerClientBinder();
+ void invokeSurfaceComposerTransaction();
+ void getWindowInfo(gui::WindowInfo*);
+ sp<SurfaceControl> makeSurfaceControl();
+ BlurRegion getBlurRegion();
+ void fuzzOnPullAtom();
+ gui::DisplayModeSpecs getDisplayModeSpecs();
+
+ FuzzedDataProvider mFdp;
+};
+
+gui::DisplayModeSpecs SurfaceComposerClientFuzzer::getDisplayModeSpecs() {
+ const auto getRefreshRateRange = [&] {
+ gui::DisplayModeSpecs::RefreshRateRanges::RefreshRateRange range;
+ range.min = mFdp.ConsumeFloatingPoint<float>();
+ range.max = mFdp.ConsumeFloatingPoint<float>();
+ return range;
+ };
+
+ const auto getRefreshRateRanges = [&] {
+ gui::DisplayModeSpecs::RefreshRateRanges ranges;
+ ranges.physical = getRefreshRateRange();
+ ranges.render = getRefreshRateRange();
+ return ranges;
+ };
+
+ String8 displayName((mFdp.ConsumeRandomLengthString(kRandomStringMaxBytes)).c_str());
+ sp<IBinder> displayToken =
+ SurfaceComposerClient::createDisplay(displayName, mFdp.ConsumeBool() /*secure*/);
+ gui::DisplayModeSpecs specs;
+ specs.defaultMode = mFdp.ConsumeIntegral<int32_t>();
+ specs.allowGroupSwitching = mFdp.ConsumeBool();
+ specs.primaryRanges = getRefreshRateRanges();
+ specs.appRequestRanges = getRefreshRateRanges();
+ return specs;
+}
+
+BlurRegion SurfaceComposerClientFuzzer::getBlurRegion() {
+ int32_t left = mFdp.ConsumeIntegral<int32_t>();
+ int32_t right = mFdp.ConsumeIntegral<int32_t>();
+ int32_t top = mFdp.ConsumeIntegral<int32_t>();
+ int32_t bottom = mFdp.ConsumeIntegral<int32_t>();
+ uint32_t blurRadius = mFdp.ConsumeIntegral<uint32_t>();
+ float alpha = mFdp.ConsumeFloatingPoint<float>();
+ float cornerRadiusTL = mFdp.ConsumeFloatingPoint<float>();
+ float cornerRadiusTR = mFdp.ConsumeFloatingPoint<float>();
+ float cornerRadiusBL = mFdp.ConsumeFloatingPoint<float>();
+ float cornerRadiusBR = mFdp.ConsumeFloatingPoint<float>();
+ return BlurRegion{blurRadius, cornerRadiusTL, cornerRadiusTR, cornerRadiusBL,
+ cornerRadiusBR, alpha, left, top,
+ right, bottom};
+}
+
+void SurfaceComposerClientFuzzer::getWindowInfo(gui::WindowInfo* windowInfo) {
+ windowInfo->id = mFdp.ConsumeIntegral<int32_t>();
+ windowInfo->name = mFdp.ConsumeRandomLengthString(kRandomStringMaxBytes);
+ windowInfo->layoutParamsFlags = mFdp.PickValueInArray(kFlags);
+ windowInfo->layoutParamsType = mFdp.PickValueInArray(kType);
+ windowInfo->frameLeft = mFdp.ConsumeIntegral<int32_t>();
+ windowInfo->frameTop = mFdp.ConsumeIntegral<int32_t>();
+ windowInfo->frameRight = mFdp.ConsumeIntegral<int32_t>();
+ windowInfo->frameBottom = mFdp.ConsumeIntegral<int32_t>();
+ windowInfo->surfaceInset = mFdp.ConsumeIntegral<int32_t>();
+ windowInfo->alpha = mFdp.ConsumeFloatingPointInRange<float>(0, 1);
+ ui::Transform transform(mFdp.PickValueInArray(kOrientation));
+ windowInfo->transform = transform;
+ windowInfo->touchableRegion = Region(getRect(&mFdp));
+ windowInfo->replaceTouchableRegionWithCrop = mFdp.ConsumeBool();
+ windowInfo->touchOcclusionMode = mFdp.PickValueInArray(kMode);
+ windowInfo->ownerPid = mFdp.ConsumeIntegral<int32_t>();
+ windowInfo->ownerUid = mFdp.ConsumeIntegral<int32_t>();
+ windowInfo->packageName = mFdp.ConsumeRandomLengthString(kRandomStringMaxBytes);
+ windowInfo->inputConfig = mFdp.PickValueInArray(kFeatures);
+}
+
+sp<SurfaceControl> SurfaceComposerClientFuzzer::makeSurfaceControl() {
+ sp<IBinder> handle;
+ const sp<FakeBnSurfaceComposerClient> testClient(new FakeBnSurfaceComposerClient());
+ sp<SurfaceComposerClient> client = new SurfaceComposerClient(testClient);
+ sp<BnGraphicBufferProducer> producer;
+ uint32_t width = mFdp.ConsumeIntegral<uint32_t>();
+ uint32_t height = mFdp.ConsumeIntegral<uint32_t>();
+ uint32_t transformHint = mFdp.ConsumeIntegral<uint32_t>();
+ uint32_t flags = mFdp.ConsumeIntegral<uint32_t>();
+ int32_t format = mFdp.ConsumeIntegral<int32_t>();
+ int32_t layerId = mFdp.ConsumeIntegral<int32_t>();
+ std::string layerName = base::StringPrintf("#%d", layerId);
+ return new SurfaceControl(client, handle, layerId, layerName, width, height, format,
+ transformHint, flags);
+}
+
+void SurfaceComposerClientFuzzer::invokeSurfaceComposerTransaction() {
+ sp<SurfaceControl> surface = makeSurfaceControl();
+
+ SurfaceComposerClient::Transaction transaction;
+ int32_t layer = mFdp.ConsumeIntegral<int32_t>();
+ transaction.setLayer(surface, layer);
+
+ sp<SurfaceControl> relativeSurface = makeSurfaceControl();
+ transaction.setRelativeLayer(surface, relativeSurface, layer);
+
+ Region transparentRegion(getRect(&mFdp));
+ transaction.setTransparentRegionHint(surface, transparentRegion);
+ transaction.setAlpha(surface, mFdp.ConsumeFloatingPoint<float>());
+
+ transaction.setCornerRadius(surface, mFdp.ConsumeFloatingPoint<float>());
+ transaction.setBackgroundBlurRadius(surface, mFdp.ConsumeFloatingPoint<float>());
+ std::vector<BlurRegion> regions;
+ uint32_t vectorSize = mFdp.ConsumeIntegralInRange<uint32_t>(0, 100);
+ regions.resize(vectorSize);
+ for (size_t idx = 0; idx < vectorSize; ++idx) {
+ regions.push_back(getBlurRegion());
+ }
+ transaction.setBlurRegions(surface, regions);
+
+ transaction.setLayerStack(surface, {mFdp.ConsumeIntegral<uint32_t>()});
+ half3 color = {mFdp.ConsumeIntegral<uint32_t>(), mFdp.ConsumeIntegral<uint32_t>(),
+ mFdp.ConsumeIntegral<uint32_t>()};
+ transaction.setColor(surface, color);
+ transaction.setBackgroundColor(surface, color, mFdp.ConsumeFloatingPoint<float>(),
+ mFdp.PickValueInArray(kDataspaces));
+
+ transaction.setApi(surface, mFdp.ConsumeIntegral<int32_t>());
+ transaction.setFrameRateSelectionPriority(surface, mFdp.ConsumeIntegral<int32_t>());
+ transaction.setColorSpaceAgnostic(surface, mFdp.ConsumeBool() /*agnostic*/);
+
+ gui::WindowInfo windowInfo;
+ getWindowInfo(&windowInfo);
+ transaction.setInputWindowInfo(surface, windowInfo);
+ Parcel windowParcel;
+ windowInfo.writeToParcel(&windowParcel);
+ windowParcel.setDataPosition(0);
+ windowInfo.readFromParcel(&windowParcel);
+
+ windowInfo.addTouchableRegion(getRect(&mFdp));
+ int32_t pointX = mFdp.ConsumeIntegral<int32_t>();
+ int32_t pointY = mFdp.ConsumeIntegral<int32_t>();
+ windowInfo.touchableRegionContainsPoint(pointX, pointY);
+ windowInfo.frameContainsPoint(pointX, pointY);
+
+ Parcel transactionParcel;
+ transaction.writeToParcel(&transactionParcel);
+ transactionParcel.setDataPosition(0);
+ transaction.readFromParcel(&transactionParcel);
+ SurfaceComposerClient::Transaction::createFromParcel(&transactionParcel);
+}
+
+void SurfaceComposerClientFuzzer::fuzzOnPullAtom() {
+ std::string outData;
+ bool success;
+ SurfaceComposerClient::onPullAtom(mFdp.ConsumeIntegral<int32_t>(), &outData, &success);
+}
+
+void SurfaceComposerClientFuzzer::invokeSurfaceComposerClient() {
+ String8 displayName((mFdp.ConsumeRandomLengthString(kRandomStringMaxBytes)).c_str());
+ sp<IBinder> displayToken =
+ SurfaceComposerClient::createDisplay(displayName, mFdp.ConsumeBool() /*secure*/);
+ SurfaceComposerClient::setDesiredDisplayModeSpecs(displayToken, getDisplayModeSpecs());
+
+ ui::ColorMode colorMode = mFdp.PickValueInArray(kColormodes);
+ SurfaceComposerClient::setActiveColorMode(displayToken, colorMode);
+ SurfaceComposerClient::setAutoLowLatencyMode(displayToken, mFdp.ConsumeBool() /*on*/);
+ SurfaceComposerClient::setGameContentType(displayToken, mFdp.ConsumeBool() /*on*/);
+ SurfaceComposerClient::setDisplayPowerMode(displayToken, mFdp.ConsumeIntegral<int32_t>());
+ SurfaceComposerClient::doUncacheBufferTransaction(mFdp.ConsumeIntegral<uint64_t>());
+
+ SurfaceComposerClient::setDisplayBrightness(displayToken, getBrightness(&mFdp));
+ hardware::power::Boost boostId = mFdp.PickValueInArray(kBoost);
+ SurfaceComposerClient::notifyPowerBoost((int32_t)boostId);
+
+ String8 surfaceName((mFdp.ConsumeRandomLengthString(kRandomStringMaxBytes)).c_str());
+ sp<BBinder> handle(new BBinder());
+ sp<BnGraphicBufferProducer> producer;
+ sp<Surface> surfaceParent(
+ new Surface(producer, mFdp.ConsumeBool() /*controlledByApp*/, handle));
+
+ fuzzOnPullAtom();
+ SurfaceComposerClient::setDisplayContentSamplingEnabled(displayToken,
+ mFdp.ConsumeBool() /*enable*/,
+ mFdp.ConsumeIntegral<uint8_t>(),
+ mFdp.ConsumeIntegral<uint64_t>());
+
+ sp<IBinder> stopLayerHandle;
+ sp<gui::IRegionSamplingListener> listener = sp<gui::IRegionSamplingListenerDefault>::make();
+ sp<gui::IRegionSamplingListenerDelegator> sampleListener =
+ new gui::IRegionSamplingListenerDelegator(listener);
+ SurfaceComposerClient::addRegionSamplingListener(getRect(&mFdp), stopLayerHandle,
+ sampleListener);
+ sp<gui::IFpsListenerDefault> fpsListener;
+ SurfaceComposerClient::addFpsListener(mFdp.ConsumeIntegral<int32_t>(), fpsListener);
+}
+
+void SurfaceComposerClientFuzzer::invokeSurfaceComposerClientBinder() {
+ sp<FakeBnSurfaceComposerClient> client(new FakeBnSurfaceComposerClient());
+ fuzzService(client.get(), std::move(mFdp));
+}
+
+void SurfaceComposerClientFuzzer::process() {
+ invokeSurfaceComposerClient();
+ invokeSurfaceComposerTransaction();
+ invokeSurfaceComposerClientBinder();
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ SurfaceComposerClientFuzzer surfaceComposerClientFuzzer(data, size);
+ surfaceComposerClientFuzzer.process();
+ return 0;
+}
diff --git a/libs/gui/fuzzer/libgui_surfaceComposer_fuzzer.cpp b/libs/gui/fuzzer/libgui_surfaceComposer_fuzzer.cpp
new file mode 100644
index 0000000000..6d5427bc9e
--- /dev/null
+++ b/libs/gui/fuzzer/libgui_surfaceComposer_fuzzer.cpp
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2021 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <fuzzbinder/libbinder_driver.h>
+#include <fuzzer/FuzzedDataProvider.h>
+#include <libgui_fuzzer_utils.h>
+
+using namespace android;
+
+class SurfaceComposerFuzzer {
+public:
+ SurfaceComposerFuzzer(const uint8_t* data, size_t size) : mFdp(data, size){};
+ void process();
+
+private:
+ FuzzedDataProvider mFdp;
+};
+
+void SurfaceComposerFuzzer::process() {
+ sp<FakeBnSurfaceComposer> composer(new FakeBnSurfaceComposer());
+ fuzzService(composer.get(), std::move(mFdp));
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
+ SurfaceComposerFuzzer surfaceComposerFuzzer(data, size);
+ surfaceComposerFuzzer.process();
+ return 0;
+}
diff --git a/libs/gui/include/gui/AidlStatusUtil.h b/libs/gui/include/gui/AidlStatusUtil.h
new file mode 100644
index 0000000000..55be27bf35
--- /dev/null
+++ b/libs/gui/include/gui/AidlStatusUtil.h
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <binder/Status.h>
+
+// Extracted from frameworks/av/media/libaudioclient/include/media/AidlConversionUtil.h
+namespace android::gui::aidl_utils {
+
+/**
+ * Return the equivalent Android status_t from a binder exception code.
+ *
+ * Generally one should use statusTFromBinderStatus() instead.
+ *
+ * Exception codes can be generated from a remote Java service exception, translate
+ * them for use on the Native side.
+ *
+ * Note: for EX_TRANSACTION_FAILED and EX_SERVICE_SPECIFIC a more detailed error code
+ * can be found from transactionError() or serviceSpecificErrorCode().
+ */
+static inline status_t statusTFromExceptionCode(int32_t exceptionCode) {
+ using namespace ::android::binder;
+ switch (exceptionCode) {
+ case Status::EX_NONE:
+ return OK;
+ case Status::EX_SECURITY: // Java SecurityException, rethrows locally in Java
+ return PERMISSION_DENIED;
+ case Status::EX_BAD_PARCELABLE: // Java BadParcelableException, rethrows in Java
+ case Status::EX_ILLEGAL_ARGUMENT: // Java IllegalArgumentException, rethrows in Java
+ case Status::EX_NULL_POINTER: // Java NullPointerException, rethrows in Java
+ return BAD_VALUE;
+ case Status::EX_ILLEGAL_STATE: // Java IllegalStateException, rethrows in Java
+ case Status::EX_UNSUPPORTED_OPERATION: // Java UnsupportedOperationException, rethrows
+ return INVALID_OPERATION;
+ case Status::EX_HAS_REPLY_HEADER: // Native strictmode violation
+ case Status::EX_PARCELABLE: // Java bootclass loader (not standard exception), rethrows
+ case Status::EX_NETWORK_MAIN_THREAD: // Java NetworkOnMainThreadException, rethrows
+ case Status::EX_TRANSACTION_FAILED: // Native - see error code
+ case Status::EX_SERVICE_SPECIFIC: // Java ServiceSpecificException,
+ // rethrows in Java with integer error code
+ return UNKNOWN_ERROR;
+ }
+ return UNKNOWN_ERROR;
+}
+
+/**
+ * Return the equivalent Android status_t from a binder status.
+ *
+ * Used to handle errors from a AIDL method declaration
+ *
+ * [oneway] void method(type0 param0, ...)
+ *
+ * or the following (where return_type is not a status_t)
+ *
+ * return_type method(type0 param0, ...)
+ */
+static inline status_t statusTFromBinderStatus(const ::android::binder::Status &status) {
+ return status.isOk() ? OK // check OK,
+ : status.serviceSpecificErrorCode() // service-side error, not standard Java exception
+ // (fromServiceSpecificError)
+ ?: status.transactionError() // a native binder transaction error (fromStatusT)
+ ?: statusTFromExceptionCode(status.exceptionCode()); // a service-side error with a
+ // standard Java exception (fromExceptionCode)
+}
+
+/**
+ * Return a binder::Status from native service status.
+ *
+ * This is used for methods not returning an explicit status_t,
+ * where Java callers expect an exception, not an integer return value.
+ */
+static inline ::android::binder::Status binderStatusFromStatusT(
+ status_t status, const char *optionalMessage = nullptr) {
+ const char *const emptyIfNull = optionalMessage == nullptr ? "" : optionalMessage;
+ // From binder::Status instructions:
+ // Prefer a generic exception code when possible, then a service specific
+ // code, and finally a status_t for low level failures or legacy support.
+ // Exception codes and service specific errors map to nicer exceptions for
+ // Java clients.
+
+ using namespace ::android::binder;
+ switch (status) {
+ case OK:
+ return Status::ok();
+ case PERMISSION_DENIED: // throw SecurityException on Java side
+ return Status::fromExceptionCode(Status::EX_SECURITY, emptyIfNull);
+ case BAD_VALUE: // throw IllegalArgumentException on Java side
+ return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT, emptyIfNull);
+ case INVALID_OPERATION: // throw IllegalStateException on Java side
+ return Status::fromExceptionCode(Status::EX_ILLEGAL_STATE, emptyIfNull);
+ }
+
+ // A service specific error will not show on status.transactionError() so
+ // be sure to use statusTFromBinderStatus() for reliable error handling.
+
+ // throw a ServiceSpecificException.
+ return Status::fromServiceSpecificError(status, emptyIfNull);
+}
+
+} // namespace android::gui::aidl_utils
diff --git a/libs/gui/include/gui/BLASTBufferQueue.h b/libs/gui/include/gui/BLASTBufferQueue.h
index 40ffea6809..a49a85984f 100644
--- a/libs/gui/include/gui/BLASTBufferQueue.h
+++ b/libs/gui/include/gui/BLASTBufferQueue.h
@@ -44,25 +44,25 @@ public:
mCurrentlyConnected(false),
mPreviouslyConnected(false) {}
- void onDisconnect() override;
+ void onDisconnect() override EXCLUDES(mMutex);
void addAndGetFrameTimestamps(const NewFrameEventsEntry* newTimestamps,
- FrameEventHistoryDelta* outDelta) override REQUIRES(mMutex);
+ FrameEventHistoryDelta* outDelta) override EXCLUDES(mMutex);
void updateFrameTimestamps(uint64_t frameNumber, nsecs_t refreshStartTime,
const sp<Fence>& gpuCompositionDoneFence,
const sp<Fence>& presentFence, const sp<Fence>& prevReleaseFence,
CompositorTiming compositorTiming, nsecs_t latchTime,
- nsecs_t dequeueReadyTime) REQUIRES(mMutex);
- void getConnectionEvents(uint64_t frameNumber, bool* needsDisconnect);
+ nsecs_t dequeueReadyTime) EXCLUDES(mMutex);
+ void getConnectionEvents(uint64_t frameNumber, bool* needsDisconnect) EXCLUDES(mMutex);
void resizeFrameEventHistory(size_t newSize);
protected:
- void onSidebandStreamChanged() override REQUIRES(mMutex);
+ void onSidebandStreamChanged() override EXCLUDES(mMutex);
private:
const wp<BLASTBufferQueue> mBLASTBufferQueue;
- uint64_t mCurrentFrameNumber = 0;
+ uint64_t mCurrentFrameNumber GUARDED_BY(mMutex) = 0;
Mutex mMutex;
ConsumerFrameEventHistory mFrameEventHistory GUARDED_BY(mMutex);
@@ -71,9 +71,7 @@ private:
bool mPreviouslyConnected GUARDED_BY(mMutex);
};
-class BLASTBufferQueue
- : public ConsumerBase::FrameAvailableListener, public BufferItemConsumer::BufferFreedListener
-{
+class BLASTBufferQueue : public ConsumerBase::FrameAvailableListener {
public:
BLASTBufferQueue(const std::string& name, bool updateDestinationFrame = true);
BLASTBufferQueue(const std::string& name, const sp<SurfaceControl>& surface, int width,
@@ -85,7 +83,6 @@ public:
sp<Surface> getSurface(bool includeSurfaceControlHandle);
bool isSameSurfaceControl(const sp<SurfaceControl>& surfaceControl) const;
- void onBufferFreed(const wp<GraphicBuffer>&/* graphicBuffer*/) override { /* TODO */ }
void onFrameReplaced(const BufferItem& item) override;
void onFrameAvailable(const BufferItem& item) override;
void onFrameDequeued(const uint64_t) override;
@@ -99,10 +96,11 @@ public:
std::optional<uint32_t> currentMaxAcquiredBufferCount);
void releaseBufferCallbackLocked(const ReleaseCallbackId& id, const sp<Fence>& releaseFence,
std::optional<uint32_t> currentMaxAcquiredBufferCount,
- bool fakeRelease);
- void syncNextTransaction(std::function<void(SurfaceComposerClient::Transaction*)> callback,
+ bool fakeRelease) REQUIRES(mMutex);
+ bool syncNextTransaction(std::function<void(SurfaceComposerClient::Transaction*)> callback,
bool acquireSingleBuffer = true);
void stopContinuousSyncTransaction();
+ void clearSyncTransaction();
void mergeWithNextTransaction(SurfaceComposerClient::Transaction* t, uint64_t frameNumber);
void applyPendingTransactions(uint64_t frameNumber);
@@ -117,15 +115,12 @@ public:
uint32_t getLastTransformHint() const;
uint64_t getLastAcquiredFrameNum();
- void abandon();
/**
- * Set a callback to be invoked when we are hung. The boolean parameter
- * indicates whether the hang is due to an unfired fence.
- * TODO: The boolean is always true atm, unfired fence is
- * the only case we detect.
+ * Set a callback to be invoked when we are hung. The string parameter
+ * indicates the reason for the hang.
*/
- void setTransactionHangCallback(std::function<void(bool)> callback);
+ void setTransactionHangCallback(std::function<void(const std::string&)> callback);
virtual ~BLASTBufferQueue();
@@ -161,7 +156,7 @@ private:
// mNumAcquired (buffers that queued to SF) mPendingRelease.size() (buffers that are held by
// blast). This counter is read by android studio profiler.
std::string mQueuedBufferTrace;
- sp<SurfaceControl> mSurfaceControl;
+ sp<SurfaceControl> mSurfaceControl GUARDED_BY(mMutex);
mutable std::mutex mMutex;
std::condition_variable mCallbackCV;
@@ -173,6 +168,11 @@ private:
int32_t mNumFrameAvailable GUARDED_BY(mMutex) = 0;
int32_t mNumAcquired GUARDED_BY(mMutex) = 0;
+ // A value used to identify if a producer has been changed for the same SurfaceControl.
+ // This is needed to know when the frame number has been reset to make sure we don't
+ // latch stale buffers and that we don't wait on barriers from an old producer.
+ uint32_t mProducerId = 0;
+
// Keep a reference to the submitted buffers so we can release when surfaceflinger drops the
// buffer or the buffer has been presented and a new buffer is ready to be presented.
std::unordered_map<ReleaseCallbackId, BufferItem, ReleaseBufferCallbackIdHash> mSubmitted
@@ -249,7 +249,7 @@ private:
// Queues up transactions using this token in SurfaceFlinger. This prevents queued up
// transactions from other parts of the client from blocking this transaction.
- const sp<IBinder> mApplyToken GUARDED_BY(mMutex) = new BBinder();
+ const sp<IBinder> mApplyToken GUARDED_BY(mMutex) = sp<BBinder>::make();
// Guards access to mDequeueTimestamps since we cannot hold to mMutex in onFrameDequeued or
// we will deadlock.
@@ -263,7 +263,7 @@ private:
// callback for them.
std::queue<sp<SurfaceControl>> mSurfaceControlsWithPendingCallback GUARDED_BY(mMutex);
- uint32_t mCurrentMaxAcquiredBufferCount;
+ uint32_t mCurrentMaxAcquiredBufferCount GUARDED_BY(mMutex);
// Flag to determine if syncTransaction should only acquire a single buffer and then clear or
// continue to acquire buffers until explicitly cleared
@@ -287,10 +287,10 @@ private:
// need to set this flag, notably only in the case where we are transitioning from a previous
// transaction applied by us (one way, may not yet have reached server) and an upcoming
// transaction that will be applied by some sync consumer.
- bool mAppliedLastTransaction = false;
- uint64_t mLastAppliedFrameNumber = 0;
+ bool mAppliedLastTransaction GUARDED_BY(mMutex) = false;
+ uint64_t mLastAppliedFrameNumber GUARDED_BY(mMutex) = 0;
- std::function<void(bool)> mTransactionHangCallback;
+ std::function<void(const std::string&)> mTransactionHangCallback;
std::unordered_set<uint64_t> mSyncedFrameNumbers GUARDED_BY(mMutex);
};
diff --git a/libs/gui/include/gui/Choreographer.h b/libs/gui/include/gui/Choreographer.h
new file mode 100644
index 0000000000..1df9b11432
--- /dev/null
+++ b/libs/gui/include/gui/Choreographer.h
@@ -0,0 +1,140 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <android/choreographer.h>
+#include <gui/DisplayEventDispatcher.h>
+#include <jni.h>
+#include <utils/Looper.h>
+
+#include <mutex>
+#include <queue>
+#include <thread>
+
+namespace android {
+using gui::VsyncEventData;
+
+struct FrameCallback {
+ AChoreographer_frameCallback callback;
+ AChoreographer_frameCallback64 callback64;
+ AChoreographer_vsyncCallback vsyncCallback;
+ void* data;
+ nsecs_t dueTime;
+
+ inline bool operator<(const FrameCallback& rhs) const {
+ // Note that this is intentionally flipped because we want callbacks due sooner to be at
+ // the head of the queue
+ return dueTime > rhs.dueTime;
+ }
+};
+
+struct RefreshRateCallback {
+ AChoreographer_refreshRateCallback callback;
+ void* data;
+ bool firstCallbackFired = false;
+};
+
+class Choreographer;
+
+/**
+ * Implementation of AChoreographerFrameCallbackData.
+ */
+struct ChoreographerFrameCallbackDataImpl {
+ int64_t frameTimeNanos{0};
+
+ VsyncEventData vsyncEventData;
+
+ const Choreographer* choreographer;
+};
+
+class Choreographer : public DisplayEventDispatcher, public MessageHandler {
+public:
+ struct Context {
+ std::mutex lock;
+ std::vector<Choreographer*> ptrs GUARDED_BY(lock);
+ std::map<AVsyncId, int64_t> startTimes GUARDED_BY(lock);
+ bool registeredToDisplayManager GUARDED_BY(lock) = false;
+
+ std::atomic<nsecs_t> mLastKnownVsync = -1;
+ };
+ static Context gChoreographers;
+
+ explicit Choreographer(const sp<Looper>& looper, const sp<IBinder>& layerHandle = nullptr)
+ EXCLUDES(gChoreographers.lock);
+ void postFrameCallbackDelayed(AChoreographer_frameCallback cb,
+ AChoreographer_frameCallback64 cb64,
+ AChoreographer_vsyncCallback vsyncCallback, void* data,
+ nsecs_t delay);
+ void registerRefreshRateCallback(AChoreographer_refreshRateCallback cb, void* data)
+ EXCLUDES(gChoreographers.lock);
+ void unregisterRefreshRateCallback(AChoreographer_refreshRateCallback cb, void* data);
+ // Drains the queue of pending vsync periods and dispatches refresh rate
+ // updates to callbacks.
+ // The assumption is that this method is only called on a single
+ // processing thread, either by looper or by AChoreographer_handleEvents
+ void handleRefreshRateUpdates();
+ void scheduleLatestConfigRequest();
+
+ enum {
+ MSG_SCHEDULE_CALLBACKS = 0,
+ MSG_SCHEDULE_VSYNC = 1,
+ MSG_HANDLE_REFRESH_RATE_UPDATES = 2,
+ };
+ virtual void handleMessage(const Message& message) override;
+
+ static void initJVM(JNIEnv* env);
+ static Choreographer* getForThread();
+ static void signalRefreshRateCallbacks(nsecs_t vsyncPeriod) EXCLUDES(gChoreographers.lock);
+ static int64_t getStartTimeNanosForVsyncId(AVsyncId vsyncId) EXCLUDES(gChoreographers.lock);
+ virtual ~Choreographer() override EXCLUDES(gChoreographers.lock);
+ int64_t getFrameInterval() const;
+ bool inCallback() const;
+
+private:
+ Choreographer(const Choreographer&) = delete;
+
+ void dispatchVsync(nsecs_t timestamp, PhysicalDisplayId displayId, uint32_t count,
+ VsyncEventData vsyncEventData) override;
+ void dispatchHotplug(nsecs_t timestamp, PhysicalDisplayId displayId, bool connected) override;
+ void dispatchModeChanged(nsecs_t timestamp, PhysicalDisplayId displayId, int32_t modeId,
+ nsecs_t vsyncPeriod) override;
+ void dispatchNullEvent(nsecs_t, PhysicalDisplayId) override;
+ void dispatchFrameRateOverrides(nsecs_t timestamp, PhysicalDisplayId displayId,
+ std::vector<FrameRateOverride> overrides) override;
+
+ void scheduleCallbacks();
+
+ ChoreographerFrameCallbackDataImpl createFrameCallbackData(nsecs_t timestamp) const;
+ void registerStartTime() const;
+
+ std::mutex mLock;
+ // Protected by mLock
+ std::priority_queue<FrameCallback> mFrameCallbacks;
+ std::vector<RefreshRateCallback> mRefreshRateCallbacks;
+
+ nsecs_t mLatestVsyncPeriod = -1;
+ VsyncEventData mLastVsyncEventData;
+ bool mInCallback = false;
+
+ const sp<Looper> mLooper;
+ const std::thread::id mThreadId;
+
+ // Approximation of num_threads_using_choreographer * num_frames_of_history with leeway.
+ static constexpr size_t kMaxStartTimes = 250;
+};
+
+} // namespace android \ No newline at end of file
diff --git a/libs/gui/include/gui/CompositorTiming.h b/libs/gui/include/gui/CompositorTiming.h
new file mode 100644
index 0000000000..cb8ca7a15c
--- /dev/null
+++ b/libs/gui/include/gui/CompositorTiming.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <utils/Timers.h>
+
+namespace android::gui {
+
+// Expected timing of the next composited frame, based on the timing of the latest frames.
+struct CompositorTiming {
+ static constexpr nsecs_t kDefaultVsyncPeriod = 16'666'667;
+
+ CompositorTiming() = default;
+ CompositorTiming(nsecs_t vsyncDeadline, nsecs_t vsyncPeriod, nsecs_t vsyncPhase,
+ nsecs_t presentLatency);
+
+ // Time point when compositing is expected to start.
+ nsecs_t deadline = 0;
+
+ // Duration between consecutive frames. In other words, the VSYNC period.
+ nsecs_t interval = kDefaultVsyncPeriod;
+
+ // Duration between composite start and present. For missed frames, the extra latency is rounded
+ // to a multiple of the VSYNC period, such that the remainder (presentLatency % interval) always
+ // evaluates to the VSYNC phase offset.
+ nsecs_t presentLatency = kDefaultVsyncPeriod;
+};
+
+} // namespace android::gui
diff --git a/libs/gui/include/gui/DisplayCaptureArgs.h b/libs/gui/include/gui/DisplayCaptureArgs.h
index ec884cfa8c..2676e0a338 100644
--- a/libs/gui/include/gui/DisplayCaptureArgs.h
+++ b/libs/gui/include/gui/DisplayCaptureArgs.h
@@ -22,8 +22,11 @@
#include <binder/IBinder.h>
#include <binder/Parcel.h>
#include <binder/Parcelable.h>
+#include <gui/SpHash.h>
#include <ui/GraphicTypes.h>
#include <ui/PixelFormat.h>
+#include <ui/Rect.h>
+#include <unordered_set>
namespace android::gui {
@@ -38,7 +41,7 @@ struct CaptureArgs : public Parcelable {
bool captureSecureLayers{false};
int32_t uid{UNSET_UID};
// Force capture to be in a color space. If the value is ui::Dataspace::UNKNOWN, the captured
- // result will be in the display's colorspace.
+ // result will be in a colorspace appropriate for capturing the display contents
// The display may use non-RGB dataspace (ex. displayP3) that could cause pixel data could be
// different from SRGB (byte per color), and failed when checking colors in tests.
// NOTE: In normal cases, we want the screen to be captured in display's colorspace.
@@ -54,6 +57,17 @@ struct CaptureArgs : public Parcelable {
bool grayscale = false;
+ std::unordered_set<sp<IBinder>, SpHash<IBinder>> excludeHandles;
+
+ // Hint that the caller will use the screenshot animation as part of a transition animation.
+ // The canonical example would be screen rotation - in such a case any color shift in the
+ // screenshot is a detractor so composition in the display's colorspace is required.
+ // Otherwise, the system may choose a colorspace that is more appropriate for use-cases
+ // such as file encoding or for blending HDR content into an ap's UI, where the display's
+ // exact colorspace is not an appropriate intermediate result.
+ // Note that if the caller is requesting a specific dataspace, this hint does nothing.
+ bool hintForSeamlessTransition = false;
+
virtual status_t writeToParcel(Parcel* output) const;
virtual status_t readFromParcel(const Parcel* input);
};
diff --git a/libs/gui/include/gui/DisplayEventDispatcher.h b/libs/gui/include/gui/DisplayEventDispatcher.h
index a3425395bf..140efa6d97 100644
--- a/libs/gui/include/gui/DisplayEventDispatcher.h
+++ b/libs/gui/include/gui/DisplayEventDispatcher.h
@@ -23,10 +23,11 @@ using FrameRateOverride = DisplayEventReceiver::Event::FrameRateOverride;
class DisplayEventDispatcher : public LooperCallback {
public:
- explicit DisplayEventDispatcher(
- const sp<Looper>& looper,
- ISurfaceComposer::VsyncSource vsyncSource = ISurfaceComposer::eVsyncSourceApp,
- ISurfaceComposer::EventRegistrationFlags eventRegistration = {});
+ explicit DisplayEventDispatcher(const sp<Looper>& looper,
+ gui::ISurfaceComposer::VsyncSource vsyncSource =
+ gui::ISurfaceComposer::VsyncSource::eVsyncSourceApp,
+ EventRegistrationFlags eventRegistration = {},
+ const sp<IBinder>& layerHandle = nullptr);
status_t initialize();
void dispose();
diff --git a/libs/gui/include/gui/DisplayEventReceiver.h b/libs/gui/include/gui/DisplayEventReceiver.h
index cf7a4e5522..7fd6c35c5e 100644
--- a/libs/gui/include/gui/DisplayEventReceiver.h
+++ b/libs/gui/include/gui/DisplayEventReceiver.h
@@ -20,20 +20,26 @@
#include <stdint.h>
#include <sys/types.h>
+#include <ftl/flags.h>
+
#include <utils/Errors.h>
#include <utils/RefBase.h>
#include <utils/Timers.h>
+#include <android/gui/ISurfaceComposer.h>
#include <binder/IInterface.h>
-#include <gui/ISurfaceComposer.h>
#include <gui/VsyncEventData.h>
+#include <ui/DisplayId.h>
+
// ----------------------------------------------------------------------------
namespace android {
// ----------------------------------------------------------------------------
+using EventRegistrationFlags = ftl::Flags<gui::ISurfaceComposer::EventRegistration>;
+
using gui::IDisplayEventConnection;
using gui::ParcelableVsyncEventData;
using gui::VsyncEventData;
@@ -111,9 +117,10 @@ public:
* To receive ModeChanged and/or FrameRateOverrides events specify this in
* the constructor. Other events start being delivered immediately.
*/
- explicit DisplayEventReceiver(
- ISurfaceComposer::VsyncSource vsyncSource = ISurfaceComposer::eVsyncSourceApp,
- ISurfaceComposer::EventRegistrationFlags eventRegistration = {});
+ explicit DisplayEventReceiver(gui::ISurfaceComposer::VsyncSource vsyncSource =
+ gui::ISurfaceComposer::VsyncSource::eVsyncSourceApp,
+ EventRegistrationFlags eventRegistration = {},
+ const sp<IBinder>& layerHandle = nullptr);
/*
* ~DisplayEventReceiver severs the connection with SurfaceFlinger, new events
diff --git a/libs/gui/include/gui/DisplayInfo.h b/libs/gui/include/gui/DisplayInfo.h
index 74f33a2a87..42b62c755c 100644
--- a/libs/gui/include/gui/DisplayInfo.h
+++ b/libs/gui/include/gui/DisplayInfo.h
@@ -41,6 +41,8 @@ struct DisplayInfo : public Parcelable {
status_t writeToParcel(android::Parcel*) const override;
status_t readFromParcel(const android::Parcel*) override;
+
+ void dump(std::string& result, const char* prefix = "") const;
};
} // namespace android::gui \ No newline at end of file
diff --git a/libs/gui/include/gui/FenceMonitor.h b/libs/gui/include/gui/FenceMonitor.h
new file mode 100644
index 0000000000..62ceddee5f
--- /dev/null
+++ b/libs/gui/include/gui/FenceMonitor.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <cstdint>
+#include <deque>
+#include <mutex>
+
+#include <ui/Fence.h>
+
+namespace android::gui {
+
+class FenceMonitor {
+public:
+ explicit FenceMonitor(const char* name);
+ void queueFence(const sp<Fence>& fence);
+
+private:
+ void loop();
+ void threadLoop();
+
+ const char* mName;
+ uint32_t mFencesQueued;
+ uint32_t mFencesSignaled;
+ std::deque<sp<Fence>> mQueue;
+ std::condition_variable mCondition;
+ std::mutex mMutex;
+};
+
+} // namespace android::gui \ No newline at end of file
diff --git a/libs/gui/include/gui/FrameTimestamps.h b/libs/gui/include/gui/FrameTimestamps.h
index 968aa2b257..3d1be4d2eb 100644
--- a/libs/gui/include/gui/FrameTimestamps.h
+++ b/libs/gui/include/gui/FrameTimestamps.h
@@ -17,6 +17,9 @@
#ifndef ANDROID_GUI_FRAMETIMESTAMPS_H
#define ANDROID_GUI_FRAMETIMESTAMPS_H
+#include <android/gui/FrameEvent.h>
+
+#include <gui/CompositorTiming.h>
#include <ui/FenceTime.h>
#include <utils/Flattenable.h>
#include <utils/StrongPointer.h>
@@ -31,22 +34,8 @@ namespace android {
struct FrameEvents;
class FrameEventHistoryDelta;
-
-// Identifiers for all the events that may be recorded or reported.
-enum class FrameEvent {
- POSTED,
- REQUESTED_PRESENT,
- LATCH,
- ACQUIRE,
- FIRST_REFRESH_START,
- LAST_REFRESH_START,
- GPU_COMPOSITION_DONE,
- DISPLAY_PRESENT,
- DEQUEUE_READY,
- RELEASE,
- EVENT_COUNT, // Not an actual event.
-};
-
+using gui::CompositorTiming;
+using gui::FrameEvent;
// A collection of timestamps corresponding to a single frame.
struct FrameEvents {
@@ -96,12 +85,6 @@ struct FrameEvents {
std::shared_ptr<FenceTime> releaseFence{FenceTime::NO_FENCE};
};
-struct CompositorTiming {
- nsecs_t deadline{0};
- nsecs_t interval{16666667};
- nsecs_t presentLatency{16666667};
-};
-
// A short history of frames that are synchronized between the consumer and
// producer via deltas.
class FrameEventHistory {
diff --git a/libs/gui/include/gui/GLConsumer.h b/libs/gui/include/gui/GLConsumer.h
index 2f538ffb86..ba268ab17a 100644
--- a/libs/gui/include/gui/GLConsumer.h
+++ b/libs/gui/include/gui/GLConsumer.h
@@ -138,6 +138,10 @@ public:
const sp<GraphicBuffer>& buf, const Rect& cropRect,
uint32_t transform, bool filtering);
+ static void computeTransformMatrix(float outTransform[16], float bufferWidth,
+ float bufferHeight, PixelFormat pixelFormat,
+ const Rect& cropRect, uint32_t transform, bool filtering);
+
// Scale the crop down horizontally or vertically such that it has the
// same aspect ratio as the buffer does.
static Rect scaleDownCrop(const Rect& crop, uint32_t bufferWidth,
diff --git a/libs/gui/include/gui/ISurfaceComposer.h b/libs/gui/include/gui/ISurfaceComposer.h
index a610e940be..3ff6735926 100644
--- a/libs/gui/include/gui/ISurfaceComposer.h
+++ b/libs/gui/include/gui/ISurfaceComposer.h
@@ -16,19 +16,19 @@
#pragma once
+#include <android/gui/CachingHint.h>
#include <android/gui/DisplayBrightness.h>
+#include <android/gui/FrameTimelineInfo.h>
#include <android/gui/IDisplayEventConnection.h>
#include <android/gui/IFpsListener.h>
#include <android/gui/IHdrLayerInfoListener.h>
#include <android/gui/IRegionSamplingListener.h>
#include <android/gui/IScreenCaptureListener.h>
-#include <android/gui/ITransactionTraceListener.h>
#include <android/gui/ITunnelModeEnabledListener.h>
#include <android/gui/IWindowInfosListener.h>
+#include <android/gui/IWindowInfosPublisher.h>
#include <binder/IBinder.h>
#include <binder/IInterface.h>
-#include <ftl/flags.h>
-#include <gui/FrameTimelineInfo.h>
#include <gui/ITransactionCompletedListener.h>
#include <gui/SpHash.h>
#include <math/vec4.h>
@@ -57,17 +57,14 @@
namespace android {
struct client_cache_t;
-struct ComposerState;
+class ComposerState;
struct DisplayStatInfo;
struct DisplayState;
struct InputWindowCommands;
-class LayerDebugInfo;
class HdrCapabilities;
-class IGraphicBufferProducer;
-class ISurfaceComposerClient;
class Rect;
-enum class FrameEvent;
+using gui::FrameTimelineInfo;
using gui::IDisplayEventConnection;
using gui::IRegionSamplingListener;
using gui::IScreenCaptureListener;
@@ -77,6 +74,7 @@ namespace gui {
struct DisplayCaptureArgs;
struct LayerCaptureArgs;
+class LayerDebugInfo;
} // namespace gui
@@ -85,7 +83,6 @@ namespace ui {
struct DisplayMode;
struct DisplayState;
struct DynamicDisplayInfo;
-struct StaticDisplayInfo;
} // namespace ui
@@ -97,11 +94,8 @@ class ISurfaceComposer: public IInterface {
public:
DECLARE_META_INTERFACE(SurfaceComposer)
- static constexpr size_t MAX_LAYERS = 4096;
-
// flags for setTransactionState()
enum {
- eSynchronous = 0x01,
eAnimation = 0x02,
// Explicit indication that this transaction and others to follow will likely result in a
@@ -110,328 +104,20 @@ public:
// (sf vsync offset - debug.sf.early_phase_offset_ns). SurfaceFlinger will continue to be
// in the early configuration until it receives eEarlyWakeupEnd. These flags are
// expected to be used by WindowManager only and are guarded by
- // android.permission.ACCESS_SURFACE_FLINGER
+ // android.permission.WAKEUP_SURFACE_FLINGER
eEarlyWakeupStart = 0x08,
eEarlyWakeupEnd = 0x10,
eOneWay = 0x20
};
- enum VsyncSource {
- eVsyncSourceApp = 0,
- eVsyncSourceSurfaceFlinger = 1
- };
-
- enum class EventRegistration {
- modeChanged = 1 << 0,
- frameRateOverride = 1 << 1,
- };
-
- using EventRegistrationFlags = ftl::Flags<EventRegistration>;
-
- /*
- * Create a connection with SurfaceFlinger.
- */
- virtual sp<ISurfaceComposerClient> createConnection() = 0;
-
- /* return an IDisplayEventConnection */
- virtual sp<IDisplayEventConnection> createDisplayEventConnection(
- VsyncSource vsyncSource = eVsyncSourceApp,
- EventRegistrationFlags eventRegistration = {}) = 0;
-
/* open/close transactions. requires ACCESS_SURFACE_FLINGER permission */
virtual status_t setTransactionState(
- const FrameTimelineInfo& frameTimelineInfo, const Vector<ComposerState>& state,
+ const FrameTimelineInfo& frameTimelineInfo, Vector<ComposerState>& state,
const Vector<DisplayState>& displays, uint32_t flags, const sp<IBinder>& applyToken,
- const InputWindowCommands& inputWindowCommands, int64_t desiredPresentTime,
- bool isAutoTimestamp, const client_cache_t& uncacheBuffer, bool hasListenerCallbacks,
- const std::vector<ListenerCallbacks>& listenerCallbacks, uint64_t transactionId) = 0;
-
- /* signal that we're done booting.
- * Requires ACCESS_SURFACE_FLINGER permission
- */
- virtual void bootFinished() = 0;
-
- /* verify that an IGraphicBufferProducer was created by SurfaceFlinger.
- */
- virtual bool authenticateSurfaceTexture(
- const sp<IGraphicBufferProducer>& surface) const = 0;
-
- /* Returns the frame timestamps supported by SurfaceFlinger.
- */
- virtual status_t getSupportedFrameTimestamps(
- std::vector<FrameEvent>* outSupported) const = 0;
-
- /**
- * Gets immutable information about given physical display.
- */
- virtual status_t getStaticDisplayInfo(const sp<IBinder>& display, ui::StaticDisplayInfo*) = 0;
-
- /**
- * Gets dynamic information about given physical display.
- */
- virtual status_t getDynamicDisplayInfo(const sp<IBinder>& display, ui::DynamicDisplayInfo*) = 0;
-
- virtual status_t getDisplayNativePrimaries(const sp<IBinder>& display,
- ui::DisplayPrimaries& primaries) = 0;
- virtual status_t setActiveColorMode(const sp<IBinder>& display,
- ui::ColorMode colorMode) = 0;
-
- /**
- * Sets the user-preferred display mode that a device should boot in.
- */
- virtual status_t setBootDisplayMode(const sp<IBinder>& display, ui::DisplayModeId) = 0;
-
- /* Clears the frame statistics for animations.
- *
- * Requires the ACCESS_SURFACE_FLINGER permission.
- */
- virtual status_t clearAnimationFrameStats() = 0;
-
- /* Gets the frame statistics for animations.
- *
- * Requires the ACCESS_SURFACE_FLINGER permission.
- */
- virtual status_t getAnimationFrameStats(FrameStats* outStats) const = 0;
-
- /* Overrides the supported HDR modes for the given display device.
- *
- * Requires the ACCESS_SURFACE_FLINGER permission.
- */
- virtual status_t overrideHdrTypes(const sp<IBinder>& display,
- const std::vector<ui::Hdr>& hdrTypes) = 0;
-
- /* Pulls surfaceflinger atoms global stats and layer stats to pipe to statsd.
- *
- * Requires the calling uid be from system server.
- */
- virtual status_t onPullAtom(const int32_t atomId, std::string* outData, bool* success) = 0;
-
- virtual status_t enableVSyncInjections(bool enable) = 0;
-
- virtual status_t injectVSync(nsecs_t when) = 0;
-
- /* Gets the list of active layers in Z order for debugging purposes
- *
- * Requires the ACCESS_SURFACE_FLINGER permission.
- */
- virtual status_t getLayerDebugInfo(std::vector<LayerDebugInfo>* outLayers) = 0;
-
- virtual status_t getColorManagement(bool* outGetColorManagement) const = 0;
-
- /* Gets the composition preference of the default data space and default pixel format,
- * as well as the wide color gamut data space and wide color gamut pixel format.
- * If the wide color gamut data space is V0_SRGB, then it implies that the platform
- * has no wide color gamut support.
- *
- * Requires the ACCESS_SURFACE_FLINGER permission.
- */
- virtual status_t getCompositionPreference(ui::Dataspace* defaultDataspace,
- ui::PixelFormat* defaultPixelFormat,
- ui::Dataspace* wideColorGamutDataspace,
- ui::PixelFormat* wideColorGamutPixelFormat) const = 0;
- /*
- * Requires the ACCESS_SURFACE_FLINGER permission.
- */
- virtual status_t getDisplayedContentSamplingAttributes(const sp<IBinder>& display,
- ui::PixelFormat* outFormat,
- ui::Dataspace* outDataspace,
- uint8_t* outComponentMask) const = 0;
-
- /* Turns on the color sampling engine on the display.
- *
- * Requires the ACCESS_SURFACE_FLINGER permission.
- */
- virtual status_t setDisplayContentSamplingEnabled(const sp<IBinder>& display, bool enable,
- uint8_t componentMask,
- uint64_t maxFrames) = 0;
-
- /* Returns statistics on the color profile of the last frame displayed for a given display
- *
- * Requires the ACCESS_SURFACE_FLINGER permission.
- */
- virtual status_t getDisplayedContentSample(const sp<IBinder>& display, uint64_t maxFrames,
- uint64_t timestamp,
- DisplayedFrameStats* outStats) const = 0;
-
- /*
- * Gets whether SurfaceFlinger can support protected content in GPU composition.
- * Requires the ACCESS_SURFACE_FLINGER permission.
- */
- virtual status_t getProtectedContentSupport(bool* outSupported) const = 0;
-
- /* Registers a listener to stream median luma updates from SurfaceFlinger.
- *
- * The sampling area is bounded by both samplingArea and the given stopLayerHandle
- * (i.e., only layers behind the stop layer will be captured and sampled).
- *
- * Multiple listeners may be provided so long as they have independent listeners.
- * If multiple listeners are provided, the effective sampling region for each listener will
- * be bounded by whichever stop layer has a lower Z value.
- *
- * Requires the same permissions as captureLayers and captureScreen.
- */
- virtual status_t addRegionSamplingListener(const Rect& samplingArea,
- const sp<IBinder>& stopLayerHandle,
- const sp<IRegionSamplingListener>& listener) = 0;
-
- /*
- * Removes a listener that was streaming median luma updates from SurfaceFlinger.
- */
- virtual status_t removeRegionSamplingListener(const sp<IRegionSamplingListener>& listener) = 0;
-
- /* Registers a listener that streams fps updates from SurfaceFlinger.
- *
- * The listener will stream fps updates for the layer tree rooted at the layer denoted by the
- * task ID, i.e., the layer must have the task ID as part of its layer metadata with key
- * METADATA_TASK_ID. If there is no such layer, then no fps is expected to be reported.
- *
- * Multiple listeners may be supported.
- *
- * Requires the READ_FRAME_BUFFER permission.
- */
- virtual status_t addFpsListener(int32_t taskId, const sp<gui::IFpsListener>& listener) = 0;
- /*
- * Removes a listener that was streaming fps updates from SurfaceFlinger.
- */
- virtual status_t removeFpsListener(const sp<gui::IFpsListener>& listener) = 0;
-
- /* Registers a listener to receive tunnel mode enabled updates from SurfaceFlinger.
- *
- * Requires ACCESS_SURFACE_FLINGER permission.
- */
- virtual status_t addTunnelModeEnabledListener(
- const sp<gui::ITunnelModeEnabledListener>& listener) = 0;
-
- /*
- * Removes a listener that was receiving tunnel mode enabled updates from SurfaceFlinger.
- *
- * Requires ACCESS_SURFACE_FLINGER permission.
- */
- virtual status_t removeTunnelModeEnabledListener(
- const sp<gui::ITunnelModeEnabledListener>& listener) = 0;
-
- /* Sets the refresh rate boundaries for the display.
- *
- * The primary refresh rate range represents display manager's general guidance on the display
- * modes we'll consider when switching refresh rates. Unless we get an explicit signal from an
- * app, we should stay within this range.
- *
- * The app request refresh rate range allows us to consider more display modes when switching
- * refresh rates. Although we should generally stay within the primary range, specific
- * considerations, such as layer frame rate settings specified via the setFrameRate() api, may
- * cause us to go outside the primary range. We never go outside the app request range. The app
- * request range will be greater than or equal to the primary refresh rate range, never smaller.
- *
- * defaultMode is used to narrow the list of display modes SurfaceFlinger will consider
- * switching between. Only modes with a mode group and resolution matching defaultMode
- * will be considered for switching. The defaultMode corresponds to an ID of mode in the list
- * of supported modes returned from getDynamicDisplayInfo().
- */
- virtual status_t setDesiredDisplayModeSpecs(
- const sp<IBinder>& displayToken, ui::DisplayModeId defaultMode,
- bool allowGroupSwitching, float primaryRefreshRateMin, float primaryRefreshRateMax,
- float appRequestRefreshRateMin, float appRequestRefreshRateMax) = 0;
-
- virtual status_t getDesiredDisplayModeSpecs(const sp<IBinder>& displayToken,
- ui::DisplayModeId* outDefaultMode,
- bool* outAllowGroupSwitching,
- float* outPrimaryRefreshRateMin,
- float* outPrimaryRefreshRateMax,
- float* outAppRequestRefreshRateMin,
- float* outAppRequestRefreshRateMax) = 0;
-
- /*
- * Sets the global configuration for all the shadows drawn by SurfaceFlinger. Shadow follows
- * material design guidelines.
- *
- * ambientColor
- * Color to the ambient shadow. The alpha is premultiplied.
- *
- * spotColor
- * Color to the spot shadow. The alpha is premultiplied. The position of the spot shadow
- * depends on the light position.
- *
- * lightPosY/lightPosZ
- * Position of the light used to cast the spot shadow. The X value is always the display
- * width / 2.
- *
- * lightRadius
- * Radius of the light casting the shadow.
- */
- virtual status_t setGlobalShadowSettings(const half4& ambientColor, const half4& spotColor,
- float lightPosY, float lightPosZ,
- float lightRadius) = 0;
-
- /*
- * Gets whether a display supports DISPLAY_DECORATION layers.
- *
- * displayToken
- * The token of the display.
- * outSupport
- * An output parameter for whether/how the display supports
- * DISPLAY_DECORATION layers.
- *
- * Returns NO_ERROR upon success. Otherwise,
- * NAME_NOT_FOUND if the display is invalid, or
- * BAD_VALUE if the output parameter is invalid.
- */
- virtual status_t getDisplayDecorationSupport(
- const sp<IBinder>& displayToken,
- std::optional<aidl::android::hardware::graphics::common::DisplayDecorationSupport>*
- outSupport) const = 0;
-
- /*
- * Sets the intended frame rate for a surface. See ANativeWindow_setFrameRate() for more info.
- */
- virtual status_t setFrameRate(const sp<IGraphicBufferProducer>& surface, float frameRate,
- int8_t compatibility, int8_t changeFrameRateStrategy) = 0;
-
- /*
- * Set the override frame rate for a specified uid by GameManagerService.
- * Passing the frame rate and uid to SurfaceFlinger to update the override mapping
- * in the scheduler.
- */
- virtual status_t setOverrideFrameRate(uid_t uid, float frameRate) = 0;
-
- /*
- * Sets the frame timeline vsync info received from choreographer that corresponds to next
- * buffer submitted on that surface.
- */
- virtual status_t setFrameTimelineInfo(const sp<IGraphicBufferProducer>& surface,
- const FrameTimelineInfo& frameTimelineInfo) = 0;
-
- /*
- * Adds a TransactionTraceListener to listen for transaction tracing state updates.
- */
- virtual status_t addTransactionTraceListener(
- const sp<gui::ITransactionTraceListener>& listener) = 0;
-
- /**
- * Gets priority of the RenderEngine in SurfaceFlinger.
- */
- virtual int getGPUContextPriority() = 0;
-
- /**
- * Gets the number of buffers SurfaceFlinger would need acquire. This number
- * would be propagated to the client via MIN_UNDEQUEUED_BUFFERS so that the
- * client could allocate enough buffers to match SF expectations of the
- * pipeline depth. SurfaceFlinger will make sure that it will give the app at
- * least the time configured as the 'appDuration' before trying to latch
- * the buffer.
- *
- * The total buffers needed for a given configuration is basically the
- * numbers of vsyncs a single buffer is used across the stack. For the default
- * configuration a buffer is held ~1 vsync by the app, ~1 vsync by SurfaceFlinger
- * and 1 vsync by the display. The extra buffers are calculated as the
- * number of additional buffers on top of the 2 buffers already present
- * in MIN_UNDEQUEUED_BUFFERS.
- */
- virtual status_t getMaxAcquiredBufferCount(int* buffers) const = 0;
-
- virtual status_t addWindowInfosListener(
- const sp<gui::IWindowInfosListener>& windowInfosListener) const = 0;
- virtual status_t removeWindowInfosListener(
- const sp<gui::IWindowInfosListener>& windowInfosListener) const = 0;
+ InputWindowCommands inputWindowCommands, int64_t desiredPresentTime,
+ bool isAutoTimestamp, const std::vector<client_cache_t>& uncacheBuffer,
+ bool hasListenerCallbacks, const std::vector<ListenerCallbacks>& listenerCallbacks,
+ uint64_t transactionId, const std::vector<uint64_t>& mergedTransactionIds) = 0;
};
// ----------------------------------------------------------------------------
@@ -442,77 +128,77 @@ public:
// Note: BOOT_FINISHED must remain this value, it is called from
// Java by ActivityManagerService.
BOOT_FINISHED = IBinder::FIRST_CALL_TRANSACTION,
- CREATE_CONNECTION,
- GET_STATIC_DISPLAY_INFO,
- CREATE_DISPLAY_EVENT_CONNECTION,
- CREATE_DISPLAY, // Deprecated. Autogenerated by .aidl now.
- DESTROY_DISPLAY, // Deprecated. Autogenerated by .aidl now.
- GET_PHYSICAL_DISPLAY_TOKEN, // Deprecated. Autogenerated by .aidl now.
+ CREATE_CONNECTION, // Deprecated. Autogenerated by .aidl now.
+ GET_STATIC_DISPLAY_INFO, // Deprecated. Autogenerated by .aidl now.
+ CREATE_DISPLAY_EVENT_CONNECTION, // Deprecated. Autogenerated by .aidl now.
+ CREATE_DISPLAY, // Deprecated. Autogenerated by .aidl now.
+ DESTROY_DISPLAY, // Deprecated. Autogenerated by .aidl now.
+ GET_PHYSICAL_DISPLAY_TOKEN, // Deprecated. Autogenerated by .aidl now.
SET_TRANSACTION_STATE,
- AUTHENTICATE_SURFACE,
- GET_SUPPORTED_FRAME_TIMESTAMPS,
- GET_DISPLAY_MODES, // Deprecated. Use GET_DYNAMIC_DISPLAY_INFO instead.
- GET_ACTIVE_DISPLAY_MODE, // Deprecated. Use GET_DYNAMIC_DISPLAY_INFO instead.
+ AUTHENTICATE_SURFACE, // Deprecated. Autogenerated by .aidl now.
+ GET_SUPPORTED_FRAME_TIMESTAMPS, // Deprecated. Autogenerated by .aidl now.
+ GET_DISPLAY_MODES, // Deprecated. Use GET_DYNAMIC_DISPLAY_INFO instead.
+ GET_ACTIVE_DISPLAY_MODE, // Deprecated. Use GET_DYNAMIC_DISPLAY_INFO instead.
GET_DISPLAY_STATE,
- CAPTURE_DISPLAY, // Deprecated. Autogenerated by .aidl now.
- CAPTURE_LAYERS, // Deprecated. Autogenerated by .aidl now.
- CLEAR_ANIMATION_FRAME_STATS,
- GET_ANIMATION_FRAME_STATS,
- SET_POWER_MODE, // Deprecated. Autogenerated by .aidl now.
+ CAPTURE_DISPLAY, // Deprecated. Autogenerated by .aidl now.
+ CAPTURE_LAYERS, // Deprecated. Autogenerated by .aidl now.
+ CLEAR_ANIMATION_FRAME_STATS, // Deprecated. Autogenerated by .aidl now.
+ GET_ANIMATION_FRAME_STATS, // Deprecated. Autogenerated by .aidl now.
+ SET_POWER_MODE, // Deprecated. Autogenerated by .aidl now.
GET_DISPLAY_STATS,
- GET_HDR_CAPABILITIES, // Deprecated. Use GET_DYNAMIC_DISPLAY_INFO instead.
- GET_DISPLAY_COLOR_MODES, // Deprecated. Use GET_DYNAMIC_DISPLAY_INFO instead.
- GET_ACTIVE_COLOR_MODE, // Deprecated. Use GET_DYNAMIC_DISPLAY_INFO instead.
- SET_ACTIVE_COLOR_MODE,
- ENABLE_VSYNC_INJECTIONS,
- INJECT_VSYNC,
- GET_LAYER_DEBUG_INFO,
- GET_COMPOSITION_PREFERENCE,
- GET_COLOR_MANAGEMENT,
- GET_DISPLAYED_CONTENT_SAMPLING_ATTRIBUTES,
- SET_DISPLAY_CONTENT_SAMPLING_ENABLED,
+ GET_HDR_CAPABILITIES, // Deprecated. Use GET_DYNAMIC_DISPLAY_INFO instead.
+ GET_DISPLAY_COLOR_MODES, // Deprecated. Use GET_DYNAMIC_DISPLAY_INFO instead.
+ GET_ACTIVE_COLOR_MODE, // Deprecated. Use GET_DYNAMIC_DISPLAY_INFO instead.
+ SET_ACTIVE_COLOR_MODE, // Deprecated. Autogenerated by .aidl now.
+ ENABLE_VSYNC_INJECTIONS, // Deprecated. Autogenerated by .aidl now.
+ INJECT_VSYNC, // Deprecated. Autogenerated by .aidl now.
+ GET_LAYER_DEBUG_INFO, // Deprecated. Autogenerated by .aidl now.
+ GET_COMPOSITION_PREFERENCE, // Deprecated. Autogenerated by .aidl now.
+ GET_COLOR_MANAGEMENT, // Deprecated. Autogenerated by .aidl now.
+ GET_DISPLAYED_CONTENT_SAMPLING_ATTRIBUTES, // Deprecated. Autogenerated by .aidl now.
+ SET_DISPLAY_CONTENT_SAMPLING_ENABLED, // Deprecated. Autogenerated by .aidl now.
GET_DISPLAYED_CONTENT_SAMPLE,
- GET_PROTECTED_CONTENT_SUPPORT,
- IS_WIDE_COLOR_DISPLAY, // Deprecated. Autogenerated by .aidl now.
- GET_DISPLAY_NATIVE_PRIMARIES,
- GET_PHYSICAL_DISPLAY_IDS, // Deprecated. Autogenerated by .aidl now.
- ADD_REGION_SAMPLING_LISTENER,
- REMOVE_REGION_SAMPLING_LISTENER,
- SET_DESIRED_DISPLAY_MODE_SPECS,
- GET_DESIRED_DISPLAY_MODE_SPECS,
- GET_DISPLAY_BRIGHTNESS_SUPPORT, // Deprecated. Autogenerated by .aidl now.
- SET_DISPLAY_BRIGHTNESS, // Deprecated. Autogenerated by .aidl now.
- CAPTURE_DISPLAY_BY_ID, // Deprecated. Autogenerated by .aidl now.
- NOTIFY_POWER_BOOST, // Deprecated. Autogenerated by .aidl now.
+ GET_PROTECTED_CONTENT_SUPPORT, // Deprecated. Autogenerated by .aidl now.
+ IS_WIDE_COLOR_DISPLAY, // Deprecated. Autogenerated by .aidl now.
+ GET_DISPLAY_NATIVE_PRIMARIES, // Deprecated. Autogenerated by .aidl now.
+ GET_PHYSICAL_DISPLAY_IDS, // Deprecated. Autogenerated by .aidl now.
+ ADD_REGION_SAMPLING_LISTENER, // Deprecated. Autogenerated by .aidl now.
+ REMOVE_REGION_SAMPLING_LISTENER, // Deprecated. Autogenerated by .aidl now.
+ SET_DESIRED_DISPLAY_MODE_SPECS, // Deprecated. Autogenerated by .aidl now.
+ GET_DESIRED_DISPLAY_MODE_SPECS, // Deprecated. Autogenerated by .aidl now.
+ GET_DISPLAY_BRIGHTNESS_SUPPORT, // Deprecated. Autogenerated by .aidl now.
+ SET_DISPLAY_BRIGHTNESS, // Deprecated. Autogenerated by .aidl now.
+ CAPTURE_DISPLAY_BY_ID, // Deprecated. Autogenerated by .aidl now.
+ NOTIFY_POWER_BOOST, // Deprecated. Autogenerated by .aidl now.
SET_GLOBAL_SHADOW_SETTINGS,
GET_AUTO_LOW_LATENCY_MODE_SUPPORT, // Deprecated. Use GET_DYNAMIC_DISPLAY_INFO instead.
SET_AUTO_LOW_LATENCY_MODE, // Deprecated. Autogenerated by .aidl now.
GET_GAME_CONTENT_TYPE_SUPPORT, // Deprecated. Use GET_DYNAMIC_DISPLAY_INFO instead.
SET_GAME_CONTENT_TYPE, // Deprecated. Use GET_DYNAMIC_DISPLAY_INFO instead.
- SET_FRAME_RATE,
+ SET_FRAME_RATE, // Deprecated. Autogenerated by .aidl now.
// Deprecated. Use DisplayManager.setShouldAlwaysRespectAppRequestedMode(true);
ACQUIRE_FRAME_RATE_FLEXIBILITY_TOKEN,
- SET_FRAME_TIMELINE_INFO,
- ADD_TRANSACTION_TRACE_LISTENER,
+ SET_FRAME_TIMELINE_INFO, // Deprecated. Autogenerated by .aidl now.
+ ADD_TRANSACTION_TRACE_LISTENER, // Deprecated. Autogenerated by .aidl now.
GET_GPU_CONTEXT_PRIORITY,
GET_MAX_ACQUIRED_BUFFER_COUNT,
- GET_DYNAMIC_DISPLAY_INFO,
- ADD_FPS_LISTENER,
- REMOVE_FPS_LISTENER,
- OVERRIDE_HDR_TYPES,
- ADD_HDR_LAYER_INFO_LISTENER, // Deprecated. Autogenerated by .aidl now.
- REMOVE_HDR_LAYER_INFO_LISTENER, // Deprecated. Autogenerated by .aidl now.
- ON_PULL_ATOM,
- ADD_TUNNEL_MODE_ENABLED_LISTENER,
- REMOVE_TUNNEL_MODE_ENABLED_LISTENER,
- ADD_WINDOW_INFOS_LISTENER,
- REMOVE_WINDOW_INFOS_LISTENER,
- GET_PRIMARY_PHYSICAL_DISPLAY_ID, // Deprecated. Autogenerated by .aidl now.
+ GET_DYNAMIC_DISPLAY_INFO, // Deprecated. Autogenerated by .aidl now.
+ ADD_FPS_LISTENER, // Deprecated. Autogenerated by .aidl now.
+ REMOVE_FPS_LISTENER, // Deprecated. Autogenerated by .aidl now.
+ OVERRIDE_HDR_TYPES, // Deprecated. Autogenerated by .aidl now.
+ ADD_HDR_LAYER_INFO_LISTENER, // Deprecated. Autogenerated by .aidl now.
+ REMOVE_HDR_LAYER_INFO_LISTENER, // Deprecated. Autogenerated by .aidl now.
+ ON_PULL_ATOM, // Deprecated. Autogenerated by .aidl now.
+ ADD_TUNNEL_MODE_ENABLED_LISTENER, // Deprecated. Autogenerated by .aidl now.
+ REMOVE_TUNNEL_MODE_ENABLED_LISTENER, // Deprecated. Autogenerated by .aidl now.
+ ADD_WINDOW_INFOS_LISTENER, // Deprecated. Autogenerated by .aidl now.
+ REMOVE_WINDOW_INFOS_LISTENER, // Deprecated. Autogenerated by .aidl now.
+ GET_PRIMARY_PHYSICAL_DISPLAY_ID, // Deprecated. Autogenerated by .aidl now.
GET_DISPLAY_DECORATION_SUPPORT,
GET_BOOT_DISPLAY_MODE_SUPPORT, // Deprecated. Autogenerated by .aidl now.
- SET_BOOT_DISPLAY_MODE,
- CLEAR_BOOT_DISPLAY_MODE, // Deprecated. Autogenerated by .aidl now.
- SET_OVERRIDE_FRAME_RATE,
+ SET_BOOT_DISPLAY_MODE, // Deprecated. Autogenerated by .aidl now.
+ CLEAR_BOOT_DISPLAY_MODE, // Deprecated. Autogenerated by .aidl now.
+ SET_OVERRIDE_FRAME_RATE, // Deprecated. Autogenerated by .aidl now.
// Always append new enum to the end.
};
diff --git a/libs/gui/include/gui/ISurfaceComposerClient.h b/libs/gui/include/gui/ISurfaceComposerClient.h
deleted file mode 100644
index 9e9e191480..0000000000
--- a/libs/gui/include/gui/ISurfaceComposerClient.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <binder/IInterface.h>
-#include <binder/SafeInterface.h>
-#include <gui/LayerMetadata.h>
-#include <ui/PixelFormat.h>
-
-#include <unordered_map>
-
-namespace android {
-
-class FrameStats;
-class IGraphicBufferProducer;
-
-class ISurfaceComposerClient : public IInterface {
-public:
- DECLARE_META_INTERFACE(SurfaceComposerClient)
-
- // flags for createSurface()
- enum { // (keep in sync with SurfaceControl.java)
- eHidden = 0x00000004,
- eDestroyBackbuffer = 0x00000020,
- eSkipScreenshot = 0x00000040,
- eSecure = 0x00000080,
- eNonPremultiplied = 0x00000100,
- eOpaque = 0x00000400,
- eProtectedByApp = 0x00000800,
- eProtectedByDRM = 0x00001000,
- eCursorWindow = 0x00002000,
- eNoColorFill = 0x00004000,
-
- eFXSurfaceBufferQueue = 0x00000000,
- eFXSurfaceEffect = 0x00020000,
- eFXSurfaceBufferState = 0x00040000,
- eFXSurfaceContainer = 0x00080000,
- eFXSurfaceMask = 0x000F0000,
- };
-
- // TODO(b/172002646): Clean up the Surface Creation Arguments
- /*
- * Requires ACCESS_SURFACE_FLINGER permission
- */
- virtual status_t createSurface(const String8& name, uint32_t w, uint32_t h, PixelFormat format,
- uint32_t flags, const sp<IBinder>& parent,
- LayerMetadata metadata, sp<IBinder>* handle,
- sp<IGraphicBufferProducer>* gbp, int32_t* outLayerId,
- uint32_t* outTransformHint) = 0;
-
- /*
- * Requires ACCESS_SURFACE_FLINGER permission
- */
- virtual status_t createWithSurfaceParent(const String8& name, uint32_t w, uint32_t h,
- PixelFormat format, uint32_t flags,
- const sp<IGraphicBufferProducer>& parent,
- LayerMetadata metadata, sp<IBinder>* handle,
- sp<IGraphicBufferProducer>* gbp, int32_t* outLayerId,
- uint32_t* outTransformHint) = 0;
-
- /*
- * Requires ACCESS_SURFACE_FLINGER permission
- */
- virtual status_t clearLayerFrameStats(const sp<IBinder>& handle) const = 0;
-
- /*
- * Requires ACCESS_SURFACE_FLINGER permission
- */
- virtual status_t getLayerFrameStats(const sp<IBinder>& handle, FrameStats* outStats) const = 0;
-
- virtual status_t mirrorSurface(const sp<IBinder>& mirrorFromHandle, sp<IBinder>* outHandle,
- int32_t* outLayerId) = 0;
-};
-
-class BnSurfaceComposerClient : public SafeBnInterface<ISurfaceComposerClient> {
-public:
- BnSurfaceComposerClient()
- : SafeBnInterface<ISurfaceComposerClient>("BnSurfaceComposerClient") {}
-
- status_t onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) override;
-};
-
-} // namespace android
diff --git a/libs/gui/include/gui/ITransactionCompletedListener.h b/libs/gui/include/gui/ITransactionCompletedListener.h
index cc136bb40a..39bcb4a56c 100644
--- a/libs/gui/include/gui/ITransactionCompletedListener.h
+++ b/libs/gui/include/gui/ITransactionCompletedListener.h
@@ -40,10 +40,15 @@ class ListenerCallbacks;
class CallbackId : public Parcelable {
public:
int64_t id;
- enum class Type : int32_t { ON_COMPLETE, ON_COMMIT } type;
+ enum class Type : int32_t {
+ ON_COMPLETE = 0,
+ ON_COMMIT = 1,
+ /*reserved for serialization = 2*/
+ } type;
+ bool includeJankData; // Only respected for ON_COMPLETE callbacks.
CallbackId() {}
- CallbackId(int64_t id, Type type) : id(id), type(type) {}
+ CallbackId(int64_t id, Type type) : id(id), type(type), includeJankData(false) {}
status_t writeToParcel(Parcel* output) const override;
status_t readFromParcel(const Parcel* input) override;
@@ -132,7 +137,7 @@ public:
SurfaceStats() = default;
SurfaceStats(const sp<IBinder>& sc, std::variant<nsecs_t, sp<Fence>> acquireTimeOrFence,
- const sp<Fence>& prevReleaseFence, uint32_t hint,
+ const sp<Fence>& prevReleaseFence, std::optional<uint32_t> hint,
uint32_t currentMaxAcquiredBuffersCount, FrameEventHistoryStats frameEventStats,
std::vector<JankData> jankData, ReleaseCallbackId previousReleaseCallbackId)
: surfaceControl(sc),
@@ -147,7 +152,7 @@ public:
sp<IBinder> surfaceControl;
std::variant<nsecs_t, sp<Fence>> acquireTimeOrFence = -1;
sp<Fence> previousReleaseFence;
- uint32_t transformHint = 0;
+ std::optional<uint32_t> transformHint = 0;
uint32_t currentMaxAcquiredBufferCount = 0;
FrameEventHistoryStats eventStats;
std::vector<JankData> jankData;
@@ -194,7 +199,10 @@ public:
virtual void onReleaseBuffer(ReleaseCallbackId callbackId, sp<Fence> releaseFence,
uint32_t currentMaxAcquiredBufferCount) = 0;
- virtual void onTransactionQueueStalled() = 0;
+
+ virtual void onTransactionQueueStalled(const String8& name) = 0;
+
+ virtual void onTrustedPresentationChanged(int id, bool inTrustedPresentationState) = 0;
};
class BnTransactionCompletedListener : public SafeBnInterface<ITransactionCompletedListener> {
diff --git a/libs/gui/include/gui/JankInfo.h b/libs/gui/include/gui/JankInfo.h
index ce9716f1fe..1dddeba616 100644
--- a/libs/gui/include/gui/JankInfo.h
+++ b/libs/gui/include/gui/JankInfo.h
@@ -24,9 +24,9 @@ enum JankType {
None = 0x0,
// Jank that occurs in the layers below SurfaceFlinger
DisplayHAL = 0x1,
- // SF took too long on the CPU
+ // SF took too long on the CPU; deadline missed during HWC
SurfaceFlingerCpuDeadlineMissed = 0x2,
- // SF took too long on the GPU
+ // SF took too long on the GPU; deadline missed during GPU composition
SurfaceFlingerGpuDeadlineMissed = 0x4,
// Either App or GPU took too long on the frame
AppDeadlineMissed = 0x8,
diff --git a/libs/gui/include/gui/LayerCaptureArgs.h b/libs/gui/include/gui/LayerCaptureArgs.h
index 05ff9d5b7b..fae2bcc787 100644
--- a/libs/gui/include/gui/LayerCaptureArgs.h
+++ b/libs/gui/include/gui/LayerCaptureArgs.h
@@ -20,14 +20,11 @@
#include <sys/types.h>
#include <gui/DisplayCaptureArgs.h>
-#include <gui/SpHash.h>
-#include <unordered_set>
namespace android::gui {
struct LayerCaptureArgs : CaptureArgs {
sp<IBinder> layerHandle;
- std::unordered_set<sp<IBinder>, SpHash<IBinder>> excludeHandles;
bool childrenOnly{false};
status_t writeToParcel(Parcel* output) const override;
diff --git a/libs/gui/include/gui/LayerDebugInfo.h b/libs/gui/include/gui/LayerDebugInfo.h
index af834d78df..dbb80e583c 100644
--- a/libs/gui/include/gui/LayerDebugInfo.h
+++ b/libs/gui/include/gui/LayerDebugInfo.h
@@ -25,7 +25,7 @@
#include <string>
#include <math/vec4.h>
-namespace android {
+namespace android::gui {
/* Class for transporting debug info from SurfaceFlinger to authorized
* recipients. The class is intended to be a data container. There are
@@ -52,7 +52,7 @@ public:
uint32_t mZ = 0 ;
int32_t mWidth = -1;
int32_t mHeight = -1;
- Rect mCrop = Rect::INVALID_RECT;
+ android::Rect mCrop = android::Rect::INVALID_RECT;
half4 mColor = half4(1.0_hf, 1.0_hf, 1.0_hf, 0.0_hf);
uint32_t mFlags = 0;
PixelFormat mPixelFormat = PIXEL_FORMAT_NONE;
@@ -71,4 +71,4 @@ public:
std::string to_string(const LayerDebugInfo& info);
-} // namespace android
+} // namespace android::gui
diff --git a/libs/gui/include/gui/LayerMetadata.h b/libs/gui/include/gui/LayerMetadata.h
index 27f4d379e9..9cf62bc7d6 100644
--- a/libs/gui/include/gui/LayerMetadata.h
+++ b/libs/gui/include/gui/LayerMetadata.h
@@ -20,7 +20,7 @@
#include <unordered_map>
-namespace android {
+namespace android::gui {
enum {
METADATA_OWNER_UID = 1,
@@ -30,7 +30,8 @@ enum {
METADATA_ACCESSIBILITY_ID = 5,
METADATA_OWNER_PID = 6,
METADATA_DEQUEUE_TIME = 7,
- METADATA_GAME_MODE = 8
+ METADATA_GAME_MODE = 8,
+ METADATA_CALLING_UID = 9,
};
struct LayerMetadata : public Parcelable {
@@ -65,8 +66,18 @@ enum class GameMode : int32_t {
Standard = 1,
Performance = 2,
Battery = 3,
+ Custom = 4,
- ftl_last = Battery
+ ftl_last = Custom
};
-} // namespace android
+} // namespace android::gui
+
+using android::gui::METADATA_ACCESSIBILITY_ID;
+using android::gui::METADATA_DEQUEUE_TIME;
+using android::gui::METADATA_GAME_MODE;
+using android::gui::METADATA_MOUSE_CURSOR;
+using android::gui::METADATA_OWNER_PID;
+using android::gui::METADATA_OWNER_UID;
+using android::gui::METADATA_TASK_ID;
+using android::gui::METADATA_WINDOW_TYPE;
diff --git a/libs/gui/include/gui/LayerState.h b/libs/gui/include/gui/LayerState.h
index 0071d48227..a6f503ef55 100644
--- a/libs/gui/include/gui/LayerState.h
+++ b/libs/gui/include/gui/LayerState.h
@@ -21,6 +21,8 @@
#include <stdint.h>
#include <sys/types.h>
+#include <android/gui/IWindowInfosReportedListener.h>
+#include <android/gui/TrustedPresentationThresholds.h>
#include <android/native_window.h>
#include <gui/IGraphicBufferProducer.h>
#include <gui/ITransactionCompletedListener.h>
@@ -51,7 +53,11 @@
namespace android {
class Parcel;
-class ISurfaceComposerClient;
+
+using gui::ISurfaceComposerClient;
+using gui::LayerMetadata;
+
+using gui::TrustedPresentationThresholds;
struct client_cache_t {
wp<IBinder> token = nullptr;
@@ -62,6 +68,19 @@ struct client_cache_t {
bool isValid() const { return token != nullptr; }
};
+class TrustedPresentationListener : public Parcelable {
+public:
+ sp<ITransactionCompletedListener> callbackInterface;
+ int callbackId = -1;
+
+ void invoke(bool presentedWithinThresholds) {
+ callbackInterface->onTrustedPresentationChanged(callbackId, presentedWithinThresholds);
+ }
+
+ status_t writeToParcel(Parcel* parcel) const;
+ status_t readFromParcel(const Parcel* parcel);
+};
+
class BufferData : public Parcelable {
public:
virtual ~BufferData() = default;
@@ -92,6 +111,7 @@ public:
uint64_t frameNumber = 0;
bool hasBarrier = false;
uint64_t barrierFrameNumber = 0;
+ uint32_t producerId = 0;
// Listens to when the buffer is safe to be released. This is used for blast
// layers only. The callback includes a release fence as well as the graphic
@@ -130,7 +150,7 @@ struct layer_state_t {
eLayerOpaque = 0x02, // SURFACE_OPAQUE
eLayerSkipScreenshot = 0x40, // SKIP_SCREENSHOT
eLayerSecure = 0x80, // SECURE
- // Queue up BufferStateLayer buffers instead of dropping the oldest buffer when this flag is
+ // Queue up layer buffers instead of dropping the oldest buffer when this flag is
// set. This blocks the client until all the buffers have been presented. If the buffers
// have presentation timestamps, then we may drop buffers.
eEnableBackpressure = 0x100, // ENABLE_BACKPRESSURE
@@ -140,30 +160,33 @@ struct layer_state_t {
// This is needed to maintain compatibility for SurfaceView scaling behavior.
// See SurfaceView scaling behavior for more details.
eIgnoreDestinationFrame = 0x400,
+ eLayerIsRefreshRateIndicator = 0x800, // REFRESH_RATE_INDICATOR
};
enum {
ePositionChanged = 0x00000001,
eLayerChanged = 0x00000002,
- eSizeChanged = 0x00000004,
+ eTrustedPresentationInfoChanged = 0x00000004,
eAlphaChanged = 0x00000008,
eMatrixChanged = 0x00000010,
eTransparentRegionChanged = 0x00000020,
eFlagsChanged = 0x00000040,
eLayerStackChanged = 0x00000080,
+ eFlushJankData = 0x00000100,
+ eCachingHintChanged = 0x00000200,
eDimmingEnabledChanged = 0x00000400,
eShadowRadiusChanged = 0x00000800,
- /* unused 0x00001000, */
+ eRenderBorderChanged = 0x00001000,
eBufferCropChanged = 0x00002000,
eRelativeLayerChanged = 0x00004000,
eReparent = 0x00008000,
eColorChanged = 0x00010000,
- eDestroySurface = 0x00020000,
- eTransformChanged = 0x00040000,
+ /* unused = 0x00020000, */
+ eBufferTransformChanged = 0x00040000,
eTransformToDisplayInverseChanged = 0x00080000,
eCropChanged = 0x00100000,
eBufferChanged = 0x00200000,
- /* unused 0x00400000, */
+ eDefaultFrameRateCompatibilityChanged = 0x00400000,
eDataspaceChanged = 0x00800000,
eHdrMetadataChanged = 0x01000000,
eSurfaceDamageRegionChanged = 0x02000000,
@@ -188,7 +211,9 @@ struct layer_state_t {
eAutoRefreshChanged = 0x1000'00000000,
eStretchChanged = 0x2000'00000000,
eTrustedOverlayChanged = 0x4000'00000000,
- eDropInputModeChanged = 0x8000'00000000
+ eDropInputModeChanged = 0x8000'00000000,
+ eExtendedRangeBrightnessChanged = 0x10000'00000000,
+
};
layer_state_t();
@@ -196,7 +221,63 @@ struct layer_state_t {
void merge(const layer_state_t& other);
status_t write(Parcel& output) const;
status_t read(const Parcel& input);
+ // Compares two layer_state_t structs and returns a set of change flags describing all the
+ // states that are different.
+ uint64_t diff(const layer_state_t& other) const;
bool hasBufferChanges() const;
+
+ // Layer hierarchy updates.
+ static constexpr uint64_t HIERARCHY_CHANGES = layer_state_t::eLayerChanged |
+ layer_state_t::eRelativeLayerChanged | layer_state_t::eReparent |
+ layer_state_t::eLayerStackChanged;
+
+ // Geometry updates.
+ static constexpr uint64_t GEOMETRY_CHANGES = layer_state_t::eBufferCropChanged |
+ layer_state_t::eBufferTransformChanged | layer_state_t::eCornerRadiusChanged |
+ layer_state_t::eCropChanged | layer_state_t::eDestinationFrameChanged |
+ layer_state_t::eMatrixChanged | layer_state_t::ePositionChanged |
+ layer_state_t::eTransformToDisplayInverseChanged |
+ layer_state_t::eTransparentRegionChanged;
+
+ // Buffer and related updates.
+ static constexpr uint64_t BUFFER_CHANGES = layer_state_t::eApiChanged |
+ layer_state_t::eBufferChanged | layer_state_t::eBufferCropChanged |
+ layer_state_t::eBufferTransformChanged | layer_state_t::eDataspaceChanged |
+ layer_state_t::eSidebandStreamChanged | layer_state_t::eSurfaceDamageRegionChanged |
+ layer_state_t::eTransformToDisplayInverseChanged |
+ layer_state_t::eTransparentRegionChanged |
+ layer_state_t::eExtendedRangeBrightnessChanged;
+
+ // Content updates.
+ static constexpr uint64_t CONTENT_CHANGES = layer_state_t::BUFFER_CHANGES |
+ layer_state_t::eAlphaChanged | layer_state_t::eAutoRefreshChanged |
+ layer_state_t::eBackgroundBlurRadiusChanged | layer_state_t::eBackgroundColorChanged |
+ layer_state_t::eBlurRegionsChanged | layer_state_t::eColorChanged |
+ layer_state_t::eColorSpaceAgnosticChanged | layer_state_t::eColorTransformChanged |
+ layer_state_t::eCornerRadiusChanged | layer_state_t::eDimmingEnabledChanged |
+ layer_state_t::eHdrMetadataChanged | layer_state_t::eRenderBorderChanged |
+ layer_state_t::eShadowRadiusChanged | layer_state_t::eStretchChanged;
+
+ // Changes which invalidates the layer's visible region in CE.
+ static constexpr uint64_t CONTENT_DIRTY = layer_state_t::CONTENT_CHANGES |
+ layer_state_t::GEOMETRY_CHANGES | layer_state_t::HIERARCHY_CHANGES;
+
+ // Changes affecting child states.
+ static constexpr uint64_t AFFECTS_CHILDREN = layer_state_t::GEOMETRY_CHANGES |
+ layer_state_t::HIERARCHY_CHANGES | layer_state_t::eAlphaChanged |
+ layer_state_t::eColorTransformChanged | layer_state_t::eCornerRadiusChanged |
+ layer_state_t::eFlagsChanged | layer_state_t::eTrustedOverlayChanged |
+ layer_state_t::eFrameRateChanged | layer_state_t::eFixedTransformHintChanged;
+
+ // Changes affecting data sent to input.
+ static constexpr uint64_t INPUT_CHANGES = layer_state_t::GEOMETRY_CHANGES |
+ layer_state_t::HIERARCHY_CHANGES | layer_state_t::eInputInfoChanged |
+ layer_state_t::eDropInputModeChanged | layer_state_t::eTrustedOverlayChanged;
+
+ // Changes that affect the visible region on a display.
+ static constexpr uint64_t VISIBLE_REGION_CHANGES =
+ layer_state_t::GEOMETRY_CHANGES | layer_state_t::HIERARCHY_CHANGES;
+
bool hasValidBuffer() const;
void sanitize(int32_t permissions);
@@ -207,6 +288,11 @@ struct layer_state_t {
float dsdy{0};
status_t write(Parcel& output) const;
status_t read(const Parcel& input);
+ inline bool operator==(const matrix22_t& other) const {
+ return std::tie(dsdx, dtdx, dtdy, dsdy) ==
+ std::tie(other.dsdx, other.dtdx, other.dtdy, other.dsdy);
+ }
+ inline bool operator!=(const matrix22_t& other) const { return !(*this == other); }
};
sp<IBinder> surface;
int32_t layerId;
@@ -214,28 +300,23 @@ struct layer_state_t {
float x;
float y;
int32_t z;
- uint32_t w;
- uint32_t h;
ui::LayerStack layerStack = ui::DEFAULT_LAYER_STACK;
- float alpha;
uint32_t flags;
uint32_t mask;
uint8_t reserved;
matrix22_t matrix;
float cornerRadius;
uint32_t backgroundBlurRadius;
- sp<SurfaceControl> reparentSurfaceControl;
sp<SurfaceControl> relativeLayerSurfaceControl;
sp<SurfaceControl> parentSurfaceControlForChild;
- half3 color;
+ half4 color;
// non POD must be last. see write/read
Region transparentRegion;
-
- uint32_t transform;
+ uint32_t bufferTransform;
bool transformToDisplayInverse;
Rect crop;
std::shared_ptr<BufferData> bufferData = nullptr;
@@ -247,13 +328,13 @@ struct layer_state_t {
mat4 colorTransform;
std::vector<BlurRegion> blurRegions;
- sp<gui::WindowInfoHandle> windowInfoHandle = new gui::WindowInfoHandle();
+ sp<gui::WindowInfoHandle> windowInfoHandle = sp<gui::WindowInfoHandle>::make();
LayerMetadata metadata;
// The following refer to the alpha, and dataspace, respectively of
// the background color layer
- float bgColorAlpha;
+ half4 bgColor;
ui::Dataspace bgColorDataspace;
// A color space agnostic layer means the color of this layer can be
@@ -273,6 +354,9 @@ struct layer_state_t {
int8_t frameRateCompatibility;
int8_t changeFrameRateStrategy;
+ // Default frame rate compatibility used to set the layer refresh rate votetype.
+ int8_t defaultFrameRateCompatibility;
+
// Set by window manager indicating the layer and all its children are
// in a different orientation than the display. The hint suggests that
// the graphic producers should receive a transform hint as if the
@@ -291,6 +375,11 @@ struct layer_state_t {
// should be trusted for input occlusion detection purposes
bool isTrustedOverlay;
+ // Flag to indicate if border needs to be enabled on the layer
+ bool borderEnabled;
+ float borderWidth;
+ half4 borderColor;
+
// Stretch effect to be applied to this layer
StretchEffect stretchEffect;
@@ -301,9 +390,17 @@ struct layer_state_t {
gui::DropInputMode dropInputMode;
bool dimmingEnabled;
+ float currentHdrSdrRatio = 1.f;
+ float desiredHdrSdrRatio = 1.f;
+
+ gui::CachingHint cachingHint = gui::CachingHint::Enabled;
+
+ TrustedPresentationThresholds trustedPresentationThresholds;
+ TrustedPresentationListener trustedPresentationListener;
};
-struct ComposerState {
+class ComposerState {
+public:
layer_state_t state;
status_t write(Parcel& output) const;
status_t read(const Parcel& input);
@@ -353,7 +450,9 @@ struct DisplayState {
struct InputWindowCommands {
std::vector<gui::FocusRequest> focusRequests;
- bool syncInputWindows{false};
+ std::unordered_set<sp<gui::IWindowInfosReportedListener>,
+ SpHash<gui::IWindowInfosReportedListener>>
+ windowInfosReportedListeners;
// Merges the passed in commands and returns true if there were any changes.
bool merge(const InputWindowCommands& other);
diff --git a/libs/gui/include/gui/TransactionTracing.h b/libs/gui/include/gui/LayerStatePermissions.h
index 9efba47a18..a90f30c621 100644
--- a/libs/gui/include/gui/TransactionTracing.h
+++ b/libs/gui/include/gui/LayerStatePermissions.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Android Open Source Project
+ * Copyright (C) 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,28 +14,16 @@
* limitations under the License.
*/
-#pragma once
-
-#include <android/gui/BnTransactionTraceListener.h>
-#include <utils/Mutex.h>
+#include <stdint.h>
+#include <string>
+#include <unordered_map>
namespace android {
-
-class TransactionTraceListener : public gui::BnTransactionTraceListener {
- static std::mutex sMutex;
- static sp<TransactionTraceListener> sInstance;
-
- TransactionTraceListener();
-
+class LayerStatePermissions {
public:
- static sp<TransactionTraceListener> getInstance();
-
- binder::Status onToggled(bool enabled) override;
-
- bool isTracingEnabled();
+ static uint32_t getTransactionPermissions(int pid, int uid);
private:
- bool mTracingEnabled = false;
+ static std::unordered_map<std::string, int> mPermissionMap;
};
-
-} // namespace android
+} // namespace android \ No newline at end of file
diff --git a/libs/gui/include/gui/ScreenCaptureResults.h b/libs/gui/include/gui/ScreenCaptureResults.h
index 724c11c881..6e17791a29 100644
--- a/libs/gui/include/gui/ScreenCaptureResults.h
+++ b/libs/gui/include/gui/ScreenCaptureResults.h
@@ -19,6 +19,7 @@
#include <binder/Parcel.h>
#include <binder/Parcelable.h>
#include <ui/Fence.h>
+#include <ui/FenceResult.h>
#include <ui/GraphicBuffer.h>
namespace android::gui {
@@ -31,11 +32,10 @@ public:
status_t readFromParcel(const android::Parcel* parcel) override;
sp<GraphicBuffer> buffer;
- sp<Fence> fence = Fence::NO_FENCE;
+ FenceResult fenceResult = Fence::NO_FENCE;
bool capturedSecureLayers{false};
bool capturedHdrLayers{false};
ui::Dataspace capturedDataspace{ui::Dataspace::V0_SRGB};
- status_t result = OK;
};
} // namespace android::gui
diff --git a/libs/gui/include/gui/Surface.h b/libs/gui/include/gui/Surface.h
index 4a552b6643..39a59e42aa 100644
--- a/libs/gui/include/gui/Surface.h
+++ b/libs/gui/include/gui/Surface.h
@@ -17,8 +17,8 @@
#ifndef ANDROID_GUI_SURFACE_H
#define ANDROID_GUI_SURFACE_H
+#include <android/gui/FrameTimelineInfo.h>
#include <gui/BufferQueueDefs.h>
-#include <gui/FrameTimelineInfo.h>
#include <gui/HdrMetadata.h>
#include <gui/IGraphicBufferProducer.h>
#include <gui/IProducerListener.h>
@@ -41,6 +41,8 @@ class ISurfaceComposer;
class ISurfaceComposer;
+using gui::FrameTimelineInfo;
+
/* This is the same as ProducerListener except that onBuffersDiscarded is
* called with a vector of graphic buffers instead of buffer slots.
*/
@@ -203,8 +205,8 @@ public:
nsecs_t* outDisplayPresentTime, nsecs_t* outDequeueReadyTime,
nsecs_t* outReleaseTime);
- status_t getWideColorSupport(bool* supported);
- status_t getHdrSupport(bool* supported);
+ status_t getWideColorSupport(bool* supported) __attribute__((__deprecated__));
+ status_t getHdrSupport(bool* supported) __attribute__((__deprecated__));
status_t getUniqueId(uint64_t* outId) const;
status_t getConsumerUsage(uint64_t* outUsage) const;
@@ -301,6 +303,10 @@ private:
int dispatchGetLastQueuedBuffer2(va_list args);
int dispatchSetFrameTimelineInfo(va_list args);
+ std::mutex mNameMutex;
+ std::string mName;
+ const char* getDebugName();
+
protected:
virtual int dequeueBuffer(ANativeWindowBuffer** buffer, int* fenceFd);
virtual int cancelBuffer(ANativeWindowBuffer* buffer, int fenceFd);
diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h
index 9033e17c53..fb57f63dad 100644
--- a/libs/gui/include/gui/SurfaceComposerClient.h
+++ b/libs/gui/include/gui/SurfaceComposerClient.h
@@ -38,6 +38,9 @@
#include <ui/GraphicTypes.h>
#include <ui/PixelFormat.h>
#include <ui/Rotation.h>
+#include <ui/StaticDisplayInfo.h>
+
+#include <android/gui/ISurfaceComposerClient.h>
#include <gui/CpuConsumer.h>
#include <gui/ISurfaceComposer.h>
@@ -52,20 +55,22 @@
namespace android {
class HdrCapabilities;
-class ISurfaceComposerClient;
class IGraphicBufferProducer;
class ITunnelModeEnabledListener;
class Region;
+class TransactionCompletedListener;
using gui::DisplayCaptureArgs;
using gui::IRegionSamplingListener;
+using gui::ISurfaceComposerClient;
using gui::LayerCaptureArgs;
+using gui::LayerMetadata;
struct SurfaceControlStats {
SurfaceControlStats(const sp<SurfaceControl>& sc, nsecs_t latchTime,
std::variant<nsecs_t, sp<Fence>> acquireTimeOrFence,
const sp<Fence>& presentFence, const sp<Fence>& prevReleaseFence,
- uint32_t hint, FrameEventHistoryStats eventStats,
+ std::optional<uint32_t> hint, FrameEventHistoryStats eventStats,
uint32_t currentMaxAcquiredBufferCount)
: surfaceControl(sc),
latchTime(latchTime),
@@ -81,7 +86,7 @@ struct SurfaceControlStats {
std::variant<nsecs_t, sp<Fence>> acquireTimeOrFence = -1;
sp<Fence> presentFence;
sp<Fence> previousReleaseFence;
- uint32_t transformHint = 0;
+ std::optional<uint32_t> transformHint = 0;
FrameEventHistoryStats frameEventStats;
uint32_t currentMaxAcquiredBufferCount = 0;
};
@@ -102,6 +107,8 @@ using SurfaceStatsCallback =
const sp<Fence>& /*presentFence*/,
const SurfaceStats& /*stats*/)>;
+using TrustedPresentationCallback = std::function<void(void*, bool)>;
+
// ---------------------------------------------------------------------------
class ReleaseCallbackThread {
@@ -141,32 +148,28 @@ public:
status_t linkToComposerDeath(const sp<IBinder::DeathRecipient>& recipient,
void* cookie = nullptr, uint32_t flags = 0);
+ // Notify the SurfaceComposerClient that the boot procedure has completed
+ static status_t bootFinished();
+
// Get transactional state of given display.
static status_t getDisplayState(const sp<IBinder>& display, ui::DisplayState*);
// Get immutable information about given physical display.
- static status_t getStaticDisplayInfo(const sp<IBinder>& display, ui::StaticDisplayInfo*);
+ static status_t getStaticDisplayInfo(int64_t, ui::StaticDisplayInfo*);
- // Get dynamic information about given physical display.
- static status_t getDynamicDisplayInfo(const sp<IBinder>& display, ui::DynamicDisplayInfo*);
+ // Get dynamic information about given physical display from display id
+ static status_t getDynamicDisplayInfoFromId(int64_t, ui::DynamicDisplayInfo*);
// Shorthand for the active display mode from getDynamicDisplayInfo().
// TODO(b/180391891): Update clients to use getDynamicDisplayInfo and remove this function.
static status_t getActiveDisplayMode(const sp<IBinder>& display, ui::DisplayMode*);
// Sets the refresh rate boundaries for the display.
- static status_t setDesiredDisplayModeSpecs(
- const sp<IBinder>& displayToken, ui::DisplayModeId defaultMode,
- bool allowGroupSwitching, float primaryRefreshRateMin, float primaryRefreshRateMax,
- float appRequestRefreshRateMin, float appRequestRefreshRateMax);
+ static status_t setDesiredDisplayModeSpecs(const sp<IBinder>& displayToken,
+ const gui::DisplayModeSpecs&);
// Gets the refresh rate boundaries for the display.
static status_t getDesiredDisplayModeSpecs(const sp<IBinder>& displayToken,
- ui::DisplayModeId* outDefaultMode,
- bool* outAllowGroupSwitching,
- float* outPrimaryRefreshRateMin,
- float* outPrimaryRefreshRateMax,
- float* outAppRequestRefreshRateMin,
- float* outAppRequestRefreshRateMax);
+ gui::DisplayModeSpecs*);
// Get the coordinates of the display's native color primaries
static status_t getDisplayNativePrimaries(const sp<IBinder>& display,
@@ -178,11 +181,24 @@ public:
// Gets if boot display mode operations are supported on a device
static status_t getBootDisplayModeSupport(bool* support);
+
+ // Gets the overlay properties of the device
+ static status_t getOverlaySupport(gui::OverlayProperties* outProperties);
+
// Sets the user-preferred display mode that a device should boot in
static status_t setBootDisplayMode(const sp<IBinder>& display, ui::DisplayModeId);
// Clears the user-preferred display mode
static status_t clearBootDisplayMode(const sp<IBinder>& display);
+ // Gets the HDR conversion capabilities of the device
+ static status_t getHdrConversionCapabilities(std::vector<gui::HdrConversionCapability>*);
+ // Sets the HDR conversion strategy for the device. in case when HdrConversionStrategy has
+ // autoAllowedHdrTypes set. Returns Hdr::INVALID in other cases.
+ static status_t setHdrConversionStrategy(gui::HdrConversionStrategy hdrConversionStrategy,
+ ui::Hdr* outPreferredHdrOutputType);
+ // Returns whether HDR conversion is supported by the device.
+ static status_t getHdrOutputConversionSupport(bool* isSupported);
+
// Sets the frame rate of a particular app (uid). This is currently called
// by GameManager.
static status_t setOverrideFrameRate(uid_t uid, float frameRate);
@@ -218,7 +234,7 @@ public:
/**
* Gets the context priority of surface flinger's render engine.
*/
- static int getGPUContextPriority();
+ static int getGpuContextPriority();
/**
* Uncaches a buffer in ISurfaceComposer. It must be uncached via a transaction so that it is
@@ -314,7 +330,7 @@ public:
uint32_t w, // width in pixel
uint32_t h, // height in pixel
PixelFormat format, // pixel-format desired
- uint32_t flags = 0, // usage flags
+ int32_t flags = 0, // usage flags
const sp<IBinder>& parentHandle = nullptr, // parentHandle
LayerMetadata metadata = LayerMetadata(), // metadata
uint32_t* outTransformHint = nullptr);
@@ -324,21 +340,11 @@ public:
uint32_t h, // height in pixel
PixelFormat format, // pixel-format desired
sp<SurfaceControl>* outSurface,
- uint32_t flags = 0, // usage flags
+ int32_t flags = 0, // usage flags
const sp<IBinder>& parentHandle = nullptr, // parentHandle
LayerMetadata metadata = LayerMetadata(), // metadata
uint32_t* outTransformHint = nullptr);
- //! Create a surface
- sp<SurfaceControl> createWithSurfaceParent(const String8& name, // name of the surface
- uint32_t w, // width in pixel
- uint32_t h, // height in pixel
- PixelFormat format, // pixel-format desired
- uint32_t flags = 0, // usage flags
- Surface* parent = nullptr, // parent
- LayerMetadata metadata = LayerMetadata(), // metadata
- uint32_t* outTransformHint = nullptr);
-
// Creates a mirrored hierarchy for the mirrorFromSurface. This returns a SurfaceControl
// which is a parent of the root of the mirrored hierarchy.
//
@@ -350,24 +356,20 @@ public:
// B B'
sp<SurfaceControl> mirrorSurface(SurfaceControl* mirrorFromSurface);
+ sp<SurfaceControl> mirrorDisplay(DisplayId displayId);
+
//! Create a virtual display
- static sp<IBinder> createDisplay(const String8& displayName, bool secure);
+ static sp<IBinder> createDisplay(const String8& displayName, bool secure,
+ float requestedRefereshRate = 0);
//! Destroy a virtual display
static void destroyDisplay(const sp<IBinder>& display);
//! Get stable IDs for connected physical displays
static std::vector<PhysicalDisplayId> getPhysicalDisplayIds();
- static status_t getPrimaryPhysicalDisplayId(PhysicalDisplayId*);
- static std::optional<PhysicalDisplayId> getInternalDisplayId();
//! Get token for a physical display given its stable ID
static sp<IBinder> getPhysicalDisplayToken(PhysicalDisplayId displayId);
- static sp<IBinder> getInternalDisplayToken();
-
- static status_t enableVSyncInjections(bool enable);
-
- static status_t injectVSync(nsecs_t when);
struct SCHash {
std::size_t operator()(const sp<SurfaceControl>& sc) const {
@@ -396,26 +398,43 @@ public:
std::unordered_set<sp<SurfaceControl>, SCHash> surfaceControls;
};
+ struct PresentationCallbackRAII : public RefBase {
+ sp<TransactionCompletedListener> mTcl;
+ int mId;
+ PresentationCallbackRAII(TransactionCompletedListener* tcl, int id);
+ virtual ~PresentationCallbackRAII();
+ };
+
class Transaction : public Parcelable {
private:
+ static sp<IBinder> sApplyToken;
void releaseBufferIfOverwriting(const layer_state_t& state);
+ static void mergeFrameTimelineInfo(FrameTimelineInfo& t, const FrameTimelineInfo& other);
+ static void clearFrameTimelineInfo(FrameTimelineInfo& t);
protected:
std::unordered_map<sp<IBinder>, ComposerState, IBinderHash> mComposerStates;
SortedVector<DisplayState> mDisplayStates;
std::unordered_map<sp<ITransactionCompletedListener>, CallbackInfo, TCLHash>
mListenerCallbacks;
+ std::vector<client_cache_t> mUncacheBuffers;
+
+ // We keep track of the last MAX_MERGE_HISTORY_LENGTH merged transaction ids.
+ // Ordered most recently merged to least recently merged.
+ static const size_t MAX_MERGE_HISTORY_LENGTH = 10u;
+ std::vector<uint64_t> mMergedTransactionIds;
uint64_t mId;
- uint32_t mForceSynchronous = 0;
uint32_t mTransactionNestCount = 0;
bool mAnimation = false;
bool mEarlyWakeupStart = false;
bool mEarlyWakeupEnd = false;
- // Indicates that the Transaction contains a buffer that should be cached
- bool mContainsBuffer = false;
+ // Indicates that the Transaction may contain buffers that should be cached. The reason this
+ // is only a guess is that buffers can be removed before cache is called. This is only a
+ // hint that at some point a buffer was added to this transaction before apply was called.
+ bool mMayContainBuffer = false;
// mDesiredPresentTime is the time in nanoseconds that the client would like the transaction
// to be presented. When it is not possible to present at exactly that time, it will be
@@ -468,16 +487,17 @@ public:
// The id is updated every time the transaction is applied.
uint64_t getId();
+ std::vector<uint64_t> getMergedTransactionIds();
+
status_t apply(bool synchronous = false, bool oneWay = false);
// Merge another transaction in to this one, clearing other
// as if it had been applied.
Transaction& merge(Transaction&& other);
Transaction& show(const sp<SurfaceControl>& sc);
Transaction& hide(const sp<SurfaceControl>& sc);
- Transaction& setPosition(const sp<SurfaceControl>& sc,
- float x, float y);
- Transaction& setSize(const sp<SurfaceControl>& sc,
- uint32_t w, uint32_t h);
+ Transaction& setPosition(const sp<SurfaceControl>& sc, float x, float y);
+ // b/243180033 remove once functions are not called from vendor code
+ Transaction& setSize(const sp<SurfaceControl>&, uint32_t, uint32_t) { return *this; }
Transaction& setLayer(const sp<SurfaceControl>& sc,
int32_t z);
@@ -527,7 +547,8 @@ public:
Transaction& setBuffer(const sp<SurfaceControl>& sc, const sp<GraphicBuffer>& buffer,
const std::optional<sp<Fence>>& fence = std::nullopt,
const std::optional<uint64_t>& frameNumber = std::nullopt,
- ReleaseBufferCallback callback = nullptr);
+ uint32_t producerId = 0, ReleaseBufferCallback callback = nullptr);
+ Transaction& unsetBuffer(const sp<SurfaceControl>& sc);
std::shared_ptr<BufferData> getAndClearBuffer(const sp<SurfaceControl>& sc);
/**
@@ -551,6 +572,9 @@ public:
Transaction& setBufferHasBarrier(const sp<SurfaceControl>& sc,
uint64_t barrierFrameNumber);
Transaction& setDataspace(const sp<SurfaceControl>& sc, ui::Dataspace dataspace);
+ Transaction& setExtendedRangeBrightness(const sp<SurfaceControl>& sc,
+ float currentBufferRatio, float desiredRatio);
+ Transaction& setCachingHint(const sp<SurfaceControl>& sc, gui::CachingHint cachingHint);
Transaction& setHdrMetadata(const sp<SurfaceControl>& sc, const HdrMetadata& hdrMetadata);
Transaction& setSurfaceDamageRegion(const sp<SurfaceControl>& sc,
const Region& surfaceDamageRegion);
@@ -572,12 +596,67 @@ public:
Transaction& addTransactionCommittedCallback(
TransactionCompletedCallbackTakesContext callback, void* callbackContext);
+ /**
+ * Set a callback to receive feedback about the presentation of a layer.
+ * When the layer is presented according to the passed in Thresholds,
+ * it is said to "enter the state", and receives the callback with true.
+ * When the conditions fall out of thresholds, it is then said to leave the
+ * state.
+ *
+ * There are a few simple thresholds:
+ * minAlpha: Lower bound on computed alpha
+ * minFractionRendered: Lower bounds on fraction of pixels that
+ * were rendered.
+ * stabilityThresholdMs: A time that alpha and fraction rendered
+ * must remain within bounds before we can "enter the state"
+ *
+ * The fraction of pixels rendered is a computation based on scale, crop
+ * and occlusion. The calculation may be somewhat counterintuitive, so we
+ * can work through an example. Imagine we have a layer with a 100x100 buffer
+ * which is occluded by (10x100) pixels on the left, and cropped by (100x10) pixels
+ * on the top. Furthermore imagine this layer is scaled by 0.9 in both dimensions.
+ * (c=crop,o=occluded,b=both,x=none
+ * b c c c
+ * o x x x
+ * o x x x
+ * o x x x
+ *
+ * We first start by computing fr=xscale*yscale=0.9*0.9=0.81, indicating
+ * that "81%" of the pixels were rendered. This corresponds to what was 100
+ * pixels being displayed in 81 pixels. This is somewhat of an abuse of
+ * language, as the information of merged pixels isn't totally lost, but
+ * we err on the conservative side.
+ *
+ * We then repeat a similar process for the crop and covered regions and
+ * accumulate the results: fr = fr * (fractionNotCropped) * (fractionNotCovered)
+ * So for this example we would get 0.9*0.9*0.9*0.9=0.65...
+ *
+ * Notice that this is not completely accurate, as we have double counted
+ * the region marked as b. However we only wanted a "lower bound" and so it
+ * is ok to err in this direction. Selection of the threshold will ultimately
+ * be somewhat arbitrary, and so there are some somewhat arbitrary decisions in
+ * this API as well.
+ *
+ * The caller must keep "PresentationCallbackRAII" alive, or the callback
+ * in SurfaceComposerClient will be unregistered.
+ */
+ Transaction& setTrustedPresentationCallback(const sp<SurfaceControl>& sc,
+ TrustedPresentationCallback callback,
+ const TrustedPresentationThresholds& thresholds,
+ void* context,
+ sp<PresentationCallbackRAII>& outCallbackOwner);
+
+ // Clear local memory in SCC
+ Transaction& clearTrustedPresentationCallback(const sp<SurfaceControl>& sc);
+
// ONLY FOR BLAST ADAPTER
Transaction& notifyProducerDisconnect(const sp<SurfaceControl>& sc);
Transaction& setInputWindowInfo(const sp<SurfaceControl>& sc, const gui::WindowInfo& info);
Transaction& setFocusedWindow(const gui::FocusRequest& request);
- Transaction& syncInputWindows();
+
+ Transaction& addWindowInfosReportedListener(
+ sp<gui::IWindowInfosReportedListener> windowInfosReportedListener);
// Set a color transform matrix on the given layer on the built-in display.
Transaction& setColorTransform(const sp<SurfaceControl>& sc, const mat3& matrix,
@@ -590,6 +669,9 @@ public:
Transaction& setFrameRate(const sp<SurfaceControl>& sc, float frameRate,
int8_t compatibility, int8_t changeFrameRateStrategy);
+ Transaction& setDefaultFrameRateCompatibility(const sp<SurfaceControl>& sc,
+ int8_t compatibility);
+
// Set by window manager indicating the layer and all its children are
// in a different orientation than the display. The hint suggests that
// the graphic producers should receive a transform hint as if the
@@ -636,6 +718,9 @@ public:
const Rect& destinationFrame);
Transaction& setDropInputMode(const sp<SurfaceControl>& sc, gui::DropInputMode mode);
+ Transaction& enableBorder(const sp<SurfaceControl>& sc, bool shouldEnable, float width,
+ const half4& color);
+
status_t setDisplaySurface(const sp<IBinder>& token,
const sp<IGraphicBufferProducer>& bufferProducer);
@@ -666,7 +751,12 @@ public:
*
* TODO (b/213644870): Remove all permissioned things from Transaction
*/
- void sanitize();
+ void sanitize(int pid, int uid);
+
+ static sp<IBinder> getDefaultApplyToken();
+ static void setDefaultApplyToken(sp<IBinder> applyToken);
+
+ static status_t sendSurfaceFlushJankDataTransaction(const sp<SurfaceControl>& sc);
};
status_t clearLayerFrameStats(const sp<IBinder>& token) const;
@@ -714,6 +804,12 @@ protected:
ReleaseCallbackThread mReleaseCallbackThread;
private:
+ // Get dynamic information about given physical display from token
+ static status_t getDynamicDisplayInfoFromToken(const sp<IBinder>& display,
+ ui::DynamicDisplayInfo*);
+
+ static void getDynamicDisplayInfoInternal(gui::DynamicDisplayInfo& ginfo,
+ ui::DynamicDisplayInfo*& outInfo);
virtual void onFirstRef();
mutable Mutex mLock;
@@ -779,7 +875,10 @@ protected:
// This is protected by mSurfaceStatsListenerMutex, but GUARDED_BY isn't supported for
// std::recursive_mutex
std::multimap<int32_t, SurfaceStatsCallbackEntry> mSurfaceStatsListeners;
- std::unordered_map<void*, std::function<void()>> mQueueStallListeners;
+ std::unordered_map<void*, std::function<void(const std::string&)>> mQueueStallListeners;
+
+ std::unordered_map<int, std::tuple<TrustedPresentationCallback, void*>>
+ mTrustedPresentationCallbacks;
public:
static sp<TransactionCompletedListener> getInstance();
@@ -792,14 +891,22 @@ public:
const std::unordered_set<sp<SurfaceControl>, SurfaceComposerClient::SCHash>&
surfaceControls,
CallbackId::Type callbackType);
+ CallbackId addCallbackFunctionLocked(
+ const TransactionCompletedCallback& callbackFunction,
+ const std::unordered_set<sp<SurfaceControl>, SurfaceComposerClient::SCHash>&
+ surfaceControls,
+ CallbackId::Type callbackType) REQUIRES(mMutex);
- void addSurfaceControlToCallbacks(
- const sp<SurfaceControl>& surfaceControl,
- const std::unordered_set<CallbackId, CallbackIdHash>& callbackIds);
+ void addSurfaceControlToCallbacks(SurfaceComposerClient::CallbackInfo& callbackInfo,
+ const sp<SurfaceControl>& surfaceControl);
- void addQueueStallListener(std::function<void()> stallListener, void* id);
+ void addQueueStallListener(std::function<void(const std::string&)> stallListener, void* id);
void removeQueueStallListener(void *id);
+ sp<SurfaceComposerClient::PresentationCallbackRAII> addTrustedPresentationCallback(
+ TrustedPresentationCallback tpc, int id, void* context);
+ void clearTrustedPresentationCallback(int id);
+
/*
* Adds a jank listener to be informed about SurfaceFlinger's jank classification for a specific
* surface. Jank classifications arrive as part of the transaction callbacks about previous
@@ -828,10 +935,12 @@ public:
// For Testing Only
static void setInstance(const sp<TransactionCompletedListener>&);
- void onTransactionQueueStalled() override;
+ void onTransactionQueueStalled(const String8& reason) override;
+
+ void onTrustedPresentationChanged(int id, bool presentedWithinThresholds) override;
private:
- ReleaseBufferCallback popReleaseBufferCallbackLocked(const ReleaseCallbackId&);
+ ReleaseBufferCallback popReleaseBufferCallbackLocked(const ReleaseCallbackId&) REQUIRES(mMutex);
static sp<TransactionCompletedListener> sInstance;
};
diff --git a/libs/gui/include/gui/SurfaceControl.h b/libs/gui/include/gui/SurfaceControl.h
index b72cf8390e..344b957ba7 100644
--- a/libs/gui/include/gui/SurfaceControl.h
+++ b/libs/gui/include/gui/SurfaceControl.h
@@ -24,17 +24,19 @@
#include <utils/RefBase.h>
#include <utils/threads.h>
+#include <android/gui/ISurfaceComposerClient.h>
+
#include <ui/FrameStats.h>
#include <ui/PixelFormat.h>
#include <ui/Region.h>
-#include <gui/ISurfaceComposerClient.h>
#include <math/vec3.h>
namespace android {
// ---------------------------------------------------------------------------
+class Choreographer;
class IGraphicBufferProducer;
class Surface;
class SurfaceComposerClient;
@@ -77,6 +79,10 @@ public:
sp<IBinder> getHandle() const;
sp<IBinder> getLayerStateHandle() const;
int32_t getLayerId() const;
+ const std::string& getName() const;
+
+ // TODO(b/267195698): Consider renaming.
+ std::shared_ptr<Choreographer> getChoreographer();
sp<IGraphicBufferProducer> getIGraphicBufferProducer();
@@ -93,9 +99,9 @@ public:
explicit SurfaceControl(const sp<SurfaceControl>& other);
SurfaceControl(const sp<SurfaceComposerClient>& client, const sp<IBinder>& handle,
- const sp<IGraphicBufferProducer>& gbp, int32_t layerId,
- uint32_t width = 0, uint32_t height = 0, PixelFormat format = 0,
- uint32_t transformHint = 0, uint32_t flags = 0);
+ int32_t layerId, const std::string& layerName, uint32_t width = 0,
+ uint32_t height = 0, PixelFormat format = 0, uint32_t transformHint = 0,
+ uint32_t flags = 0);
sp<SurfaceControl> getParentingLayer();
@@ -115,19 +121,20 @@ private:
status_t validate() const;
sp<SurfaceComposerClient> mClient;
- sp<IBinder> mHandle;
- sp<IGraphicBufferProducer> mGraphicBufferProducer;
+ sp<IBinder> mHandle;
mutable Mutex mLock;
mutable sp<Surface> mSurfaceData;
mutable sp<BLASTBufferQueue> mBbq;
mutable sp<SurfaceControl> mBbqChild;
int32_t mLayerId = 0;
+ std::string mName;
uint32_t mTransformHint = 0;
uint32_t mWidth = 0;
uint32_t mHeight = 0;
PixelFormat mFormat = PIXEL_FORMAT_NONE;
uint32_t mCreateFlags = 0;
uint64_t mFallbackFrameNumber = 100;
+ std::shared_ptr<Choreographer> mChoreographer;
};
}; // namespace android
diff --git a/libs/gui/include/gui/SyncScreenCaptureListener.h b/libs/gui/include/gui/SyncScreenCaptureListener.h
index 0784fbc058..bcf565a494 100644
--- a/libs/gui/include/gui/SyncScreenCaptureListener.h
+++ b/libs/gui/include/gui/SyncScreenCaptureListener.h
@@ -34,7 +34,9 @@ public:
ScreenCaptureResults waitForResults() {
std::future<ScreenCaptureResults> resultsFuture = resultsPromise.get_future();
const auto screenCaptureResults = resultsFuture.get();
- screenCaptureResults.fence->waitForever("");
+ if (screenCaptureResults.fenceResult.ok()) {
+ screenCaptureResults.fenceResult.value()->waitForever("");
+ }
return screenCaptureResults;
}
@@ -42,4 +44,4 @@ private:
std::promise<ScreenCaptureResults> resultsPromise;
};
-} // namespace android \ No newline at end of file
+} // namespace android
diff --git a/libs/gui/include/gui/TraceUtils.h b/libs/gui/include/gui/TraceUtils.h
index 00096158e7..441b833b5d 100644
--- a/libs/gui/include/gui/TraceUtils.h
+++ b/libs/gui/include/gui/TraceUtils.h
@@ -21,13 +21,20 @@
#include <cutils/trace.h>
#include <utils/Trace.h>
-#define ATRACE_FORMAT(fmt, ...) \
- TraceUtils::TraceEnder __traceEnder = \
- (TraceUtils::atraceFormatBegin(fmt, ##__VA_ARGS__), TraceUtils::TraceEnder())
+#define ATRACE_FORMAT(fmt, ...) \
+ TraceUtils::TraceEnder traceEnder = \
+ (CC_UNLIKELY(ATRACE_ENABLED()) && \
+ (TraceUtils::atraceFormatBegin(fmt, ##__VA_ARGS__), true), \
+ TraceUtils::TraceEnder())
-#define ATRACE_FORMAT_BEGIN(fmt, ...) TraceUtils::atraceFormatBegin(fmt, ##__VA_ARGS__)
+#define ATRACE_FORMAT_INSTANT(fmt, ...) \
+ (CC_UNLIKELY(ATRACE_ENABLED()) && (TraceUtils::instantFormat(fmt, ##__VA_ARGS__), true))
-#define ATRACE_FORMAT_INSTANT(fmt, ...) TraceUtils::intantFormat(fmt, ##__VA_ARGS__)
+#define ALOGE_AND_TRACE(fmt, ...) \
+ do { \
+ ALOGE(fmt, ##__VA_ARGS__); \
+ ATRACE_FORMAT_INSTANT(fmt, ##__VA_ARGS__); \
+ } while (false)
namespace android {
@@ -39,8 +46,6 @@ public:
};
static void atraceFormatBegin(const char* fmt, ...) {
- if (CC_LIKELY(!ATRACE_ENABLED())) return;
-
const int BUFFER_SIZE = 256;
va_list ap;
char buf[BUFFER_SIZE];
@@ -52,9 +57,7 @@ public:
ATRACE_BEGIN(buf);
}
- static void intantFormat(const char* fmt, ...) {
- if (CC_LIKELY(!ATRACE_ENABLED())) return;
-
+ static void instantFormat(const char* fmt, ...) {
const int BUFFER_SIZE = 256;
va_list ap;
char buf[BUFFER_SIZE];
@@ -65,7 +68,6 @@ public:
ATRACE_INSTANT(buf);
}
+};
-}; // class TraceUtils
-
-} /* namespace android */
+} // namespace android
diff --git a/libs/gui/include/gui/VsyncEventData.h b/libs/gui/include/gui/VsyncEventData.h
index 8e99539fe9..b40a84099c 100644
--- a/libs/gui/include/gui/VsyncEventData.h
+++ b/libs/gui/include/gui/VsyncEventData.h
@@ -16,7 +16,7 @@
#pragma once
-#include <gui/FrameTimelineInfo.h>
+#include <android/gui/FrameTimelineInfo.h>
#include <array>
@@ -24,8 +24,8 @@ namespace android::gui {
// Plain Old Data (POD) vsync data structure. For example, it can be easily used in the
// DisplayEventReceiver::Event union.
struct VsyncEventData {
- // Max amount of frame timelines is arbitrarily set to be reasonable.
- static constexpr int64_t kFrameTimelinesLength = 7;
+ // Max capacity of frame timelines is arbitrarily set to be reasonable.
+ static constexpr int64_t kFrameTimelinesCapacity = 7;
// The current frame interval in ns when this frame was scheduled.
int64_t frameInterval;
@@ -33,6 +33,9 @@ struct VsyncEventData {
// Index into the frameTimelines that represents the platform's preferred frame timeline.
uint32_t preferredFrameTimelineIndex;
+ // Size of frame timelines provided by the platform; max is kFrameTimelinesCapacity.
+ uint32_t frameTimelinesLength;
+
struct alignas(8) FrameTimeline {
// The Vsync Id corresponsing to this vsync event. This will be used to
// populate ISurfaceComposer::setFrameTimelineVsync and
@@ -45,7 +48,7 @@ struct VsyncEventData {
// The anticipated Vsync presentation time in nanos.
int64_t expectedPresentationTime;
- } frameTimelines[kFrameTimelinesLength]; // Sorted possible frame timelines.
+ } frameTimelines[kFrameTimelinesCapacity]; // Sorted possible frame timelines.
// Gets the preferred frame timeline's vsync ID.
int64_t preferredVsyncId() const;
diff --git a/libs/gui/include/gui/WindowInfo.h b/libs/gui/include/gui/WindowInfo.h
index 169f7f022b..70b2ee8e32 100644
--- a/libs/gui/include/gui/WindowInfo.h
+++ b/libs/gui/include/gui/WindowInfo.h
@@ -171,6 +171,8 @@ struct WindowInfo : public Parcelable {
static_cast<uint32_t>(os::InputConfig::SPY),
INTERCEPTS_STYLUS =
static_cast<uint32_t>(os::InputConfig::INTERCEPTS_STYLUS),
+ CLONE =
+ static_cast<uint32_t>(os::InputConfig::CLONE),
// clang-format on
};
@@ -234,9 +236,12 @@ struct WindowInfo : public Parcelable {
Type layoutParamsType = Type::UNKNOWN;
ftl::Flags<Flag> layoutParamsFlags;
- void setInputConfig(ftl::Flags<InputConfig> config, bool value);
+ // The input token for the window to which focus should be transferred when this input window
+ // can be successfully focused. If null, this input window will not transfer its focus to
+ // any other window.
+ sp<IBinder> focusTransferTarget;
- bool isClone = false;
+ void setInputConfig(ftl::Flags<InputConfig> config, bool value);
void addTouchableRegion(const Rect& region);
@@ -272,6 +277,7 @@ public:
WindowInfoHandle(const WindowInfo& other);
inline const WindowInfo* getInfo() const { return &mInfo; }
+ inline WindowInfo* editInfo() { return &mInfo; }
sp<IBinder> getToken() const;
diff --git a/libs/gui/include/gui/WindowInfosListener.h b/libs/gui/include/gui/WindowInfosListener.h
index a18a498c5e..02c8eb5ef3 100644
--- a/libs/gui/include/gui/WindowInfosListener.h
+++ b/libs/gui/include/gui/WindowInfosListener.h
@@ -16,15 +16,13 @@
#pragma once
-#include <gui/DisplayInfo.h>
-#include <gui/WindowInfo.h>
+#include <gui/WindowInfosUpdate.h>
#include <utils/RefBase.h>
namespace android::gui {
class WindowInfosListener : public virtual RefBase {
public:
- virtual void onWindowInfosChanged(const std::vector<WindowInfo>&,
- const std::vector<DisplayInfo>&) = 0;
+ virtual void onWindowInfosChanged(const WindowInfosUpdate& update) = 0;
};
-} // namespace android::gui \ No newline at end of file
+} // namespace android::gui
diff --git a/libs/gui/include/gui/WindowInfosListenerReporter.h b/libs/gui/include/gui/WindowInfosListenerReporter.h
index 3b4aed442e..684e21ad96 100644
--- a/libs/gui/include/gui/WindowInfosListenerReporter.h
+++ b/libs/gui/include/gui/WindowInfosListenerReporter.h
@@ -17,36 +17,37 @@
#pragma once
#include <android/gui/BnWindowInfosListener.h>
-#include <android/gui/IWindowInfosReportedListener.h>
+#include <android/gui/ISurfaceComposer.h>
+#include <android/gui/IWindowInfosPublisher.h>
#include <binder/IBinder.h>
-#include <gui/ISurfaceComposer.h>
#include <gui/SpHash.h>
#include <gui/WindowInfosListener.h>
+#include <gui/WindowInfosUpdate.h>
#include <unordered_set>
namespace android {
-class ISurfaceComposer;
class WindowInfosListenerReporter : public gui::BnWindowInfosListener {
public:
static sp<WindowInfosListenerReporter> getInstance();
- binder::Status onWindowInfosChanged(const std::vector<gui::WindowInfo>&,
- const std::vector<gui::DisplayInfo>&,
- const sp<gui::IWindowInfosReportedListener>&) override;
-
+ binder::Status onWindowInfosChanged(const gui::WindowInfosUpdate& update) override;
status_t addWindowInfosListener(
- const sp<gui::WindowInfosListener>& windowInfosListener, const sp<ISurfaceComposer>&,
+ const sp<gui::WindowInfosListener>& windowInfosListener,
+ const sp<gui::ISurfaceComposer>&,
std::pair<std::vector<gui::WindowInfo>, std::vector<gui::DisplayInfo>>* outInitialInfo);
status_t removeWindowInfosListener(const sp<gui::WindowInfosListener>& windowInfosListener,
- const sp<ISurfaceComposer>& surfaceComposer);
- void reconnect(const sp<ISurfaceComposer>&);
+ const sp<gui::ISurfaceComposer>& surfaceComposer);
+ void reconnect(const sp<gui::ISurfaceComposer>&);
private:
std::mutex mListenersMutex;
- std::unordered_set<sp<gui::WindowInfosListener>, SpHash<gui::WindowInfosListener>>
+ std::unordered_set<sp<gui::WindowInfosListener>, gui::SpHash<gui::WindowInfosListener>>
mWindowInfosListeners GUARDED_BY(mListenersMutex);
std::vector<gui::WindowInfo> mLastWindowInfos GUARDED_BY(mListenersMutex);
std::vector<gui::DisplayInfo> mLastDisplayInfos GUARDED_BY(mListenersMutex);
+
+ sp<gui::IWindowInfosPublisher> mWindowInfosPublisher;
+ int64_t mListenerId;
};
} // namespace android
diff --git a/libs/gui/include/gui/WindowInfosUpdate.h b/libs/gui/include/gui/WindowInfosUpdate.h
new file mode 100644
index 0000000000..2ca59fb497
--- /dev/null
+++ b/libs/gui/include/gui/WindowInfosUpdate.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <binder/Parcelable.h>
+#include <gui/DisplayInfo.h>
+#include <gui/WindowInfo.h>
+
+namespace android::gui {
+
+struct WindowInfosUpdate : public Parcelable {
+ WindowInfosUpdate() {}
+
+ WindowInfosUpdate(std::vector<WindowInfo> windowInfos, std::vector<DisplayInfo> displayInfos,
+ int64_t vsyncId, int64_t timestamp)
+ : windowInfos(std::move(windowInfos)),
+ displayInfos(std::move(displayInfos)),
+ vsyncId(vsyncId),
+ timestamp(timestamp) {}
+
+ std::vector<WindowInfo> windowInfos;
+ std::vector<DisplayInfo> displayInfos;
+ int64_t vsyncId;
+ int64_t timestamp;
+
+ status_t writeToParcel(android::Parcel*) const override;
+ status_t readFromParcel(const android::Parcel*) override;
+};
+
+} // namespace android::gui
diff --git a/libs/gui/include/gui/fake/BufferData.h b/libs/gui/include/gui/fake/BufferData.h
new file mode 100644
index 0000000000..725d11c313
--- /dev/null
+++ b/libs/gui/include/gui/fake/BufferData.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <gui/LayerState.h>
+
+namespace android::fake {
+
+// Class which exposes buffer properties from BufferData without holding on to an actual buffer
+class BufferData : public android::BufferData {
+public:
+ BufferData(uint64_t bufferId, uint32_t width, uint32_t height, int32_t pixelFormat,
+ uint64_t outUsage)
+ : mBufferId(bufferId),
+ mWidth(width),
+ mHeight(height),
+ mPixelFormat(pixelFormat),
+ mOutUsage(outUsage) {}
+ bool hasBuffer() const override { return mBufferId != 0; }
+ bool hasSameBuffer(const android::BufferData& other) const override {
+ return getId() == other.getId() && frameNumber == other.frameNumber;
+ }
+ uint32_t getWidth() const override { return mWidth; }
+ uint32_t getHeight() const override { return mHeight; }
+ uint64_t getId() const override { return mBufferId; }
+ PixelFormat getPixelFormat() const override { return mPixelFormat; }
+ uint64_t getUsage() const override { return mOutUsage; }
+
+private:
+ uint64_t mBufferId;
+ uint32_t mWidth;
+ uint32_t mHeight;
+ int32_t mPixelFormat;
+ uint64_t mOutUsage;
+};
+
+} // namespace android::fake
diff --git a/libs/gui/include/gui/test/CallbackUtils.h b/libs/gui/include/gui/test/CallbackUtils.h
index 08785b49c1..1c900e9da5 100644
--- a/libs/gui/include/gui/test/CallbackUtils.h
+++ b/libs/gui/include/gui/test/CallbackUtils.h
@@ -51,6 +51,7 @@ public:
enum Buffer {
NOT_ACQUIRED = 0,
ACQUIRED,
+ ACQUIRED_NULL,
};
enum PreviousBuffer {
@@ -133,17 +134,28 @@ private:
: mBufferResult(bufferResult), mPreviousBufferResult(previousBufferResult) {}
void verifySurfaceControlStats(const SurfaceControlStats& surfaceControlStats,
- nsecs_t latchTime) const {
+ nsecs_t /* latchTime */) const {
const auto& [surfaceControl, latch, acquireTimeOrFence, presentFence,
previousReleaseFence, transformHint, frameEvents, ignore] =
- surfaceControlStats;
-
- ASSERT_TRUE(std::holds_alternative<nsecs_t>(acquireTimeOrFence));
- ASSERT_EQ(std::get<nsecs_t>(acquireTimeOrFence) > 0,
- mBufferResult == ExpectedResult::Buffer::ACQUIRED)
- << "bad acquire time";
- ASSERT_LE(std::get<nsecs_t>(acquireTimeOrFence), latchTime)
- << "acquire time should be <= latch time";
+ surfaceControlStats;
+
+ nsecs_t acquireTime = -1;
+ if (std::holds_alternative<nsecs_t>(acquireTimeOrFence)) {
+ acquireTime = std::get<nsecs_t>(acquireTimeOrFence);
+ } else {
+ auto fence = std::get<sp<Fence>>(acquireTimeOrFence);
+ if (fence) {
+ ASSERT_EQ(fence->wait(3000), NO_ERROR);
+ acquireTime = fence->getSignalTime();
+ }
+ }
+
+ if (mBufferResult == ExpectedResult::Buffer::ACQUIRED) {
+ ASSERT_GT(acquireTime, 0) << "acquire time should be valid";
+ } else {
+ ASSERT_LE(acquireTime, 0) << "acquire time should not be valid";
+ }
+ ASSERT_EQ(acquireTime > 0, mBufferResult == ExpectedResult::Buffer::ACQUIRED);
if (mPreviousBufferResult == ExpectedResult::PreviousBuffer::RELEASED) {
ASSERT_NE(previousReleaseFence, nullptr)
diff --git a/libs/gui/include/private/gui/ComposerServiceAIDL.h b/libs/gui/include/private/gui/ComposerServiceAIDL.h
index 9a96976c0f..6352a5851c 100644
--- a/libs/gui/include/private/gui/ComposerServiceAIDL.h
+++ b/libs/gui/include/private/gui/ComposerServiceAIDL.h
@@ -20,6 +20,7 @@
#include <sys/types.h>
#include <android/gui/ISurfaceComposer.h>
+#include <ui/DisplayId.h>
#include <utils/Singleton.h>
#include <utils/StrongPointer.h>
@@ -50,28 +51,6 @@ public:
// Get a connection to the Composer Service. This will block until
// a connection is established. Returns null if permission is denied.
static sp<gui::ISurfaceComposer> getComposerService();
-
- // the following two methods are moved from ISurfaceComposer.h
- // TODO(b/74619554): Remove this stopgap once the framework is display-agnostic.
- std::optional<PhysicalDisplayId> getInternalDisplayId() const {
- std::vector<int64_t> displayIds;
- binder::Status status = mComposerService->getPhysicalDisplayIds(&displayIds);
- return (!status.isOk() || displayIds.empty())
- ? std::nullopt
- : DisplayId::fromValue<PhysicalDisplayId>(
- static_cast<uint64_t>(displayIds.front()));
- }
-
- // TODO(b/74619554): Remove this stopgap once the framework is display-agnostic.
- sp<IBinder> getInternalDisplayToken() const {
- const auto displayId = getInternalDisplayId();
- if (!displayId) return nullptr;
- sp<IBinder> display;
- binder::Status status =
- mComposerService->getPhysicalDisplayToken(static_cast<int64_t>(displayId->value),
- &display);
- return status.isOk() ? display : nullptr;
- }
};
// ---------------------------------------------------------------------------
diff --git a/libs/gui/tests/Android.bp b/libs/gui/tests/Android.bp
index 0702e0f3d5..cd35d2fe3c 100644
--- a/libs/gui/tests/Android.bp
+++ b/libs/gui/tests/Android.bp
@@ -24,6 +24,7 @@ cc_test {
"BLASTBufferQueue_test.cpp",
"BufferItemConsumer_test.cpp",
"BufferQueue_test.cpp",
+ "CompositorTiming_test.cpp",
"CpuConsumer_test.cpp",
"EndToEndNativeInputTest.cpp",
"DisplayInfo_test.cpp",
diff --git a/libs/gui/tests/BLASTBufferQueue_test.cpp b/libs/gui/tests/BLASTBufferQueue_test.cpp
index b993289e6a..a3ad6807c5 100644
--- a/libs/gui/tests/BLASTBufferQueue_test.cpp
+++ b/libs/gui/tests/BLASTBufferQueue_test.cpp
@@ -19,6 +19,7 @@
#include <gui/BLASTBufferQueue.h>
#include <android/hardware/graphics/common/1.2/types.h>
+#include <gui/AidlStatusUtil.h>
#include <gui/BufferQueueCore.h>
#include <gui/BufferQueueProducer.h>
#include <gui/FrameTimestamps.h>
@@ -31,6 +32,7 @@
#include <private/gui/ComposerService.h>
#include <private/gui/ComposerServiceAIDL.h>
#include <ui/DisplayMode.h>
+#include <ui/DisplayState.h>
#include <ui/GraphicBuffer.h>
#include <ui/GraphicTypes.h>
#include <ui/Transform.h>
@@ -115,15 +117,17 @@ public:
mBlastBufferQueueAdapter->syncNextTransaction(callback, acquireSingleBuffer);
}
- void syncNextTransaction(std::function<void(Transaction*)> callback,
+ bool syncNextTransaction(std::function<void(Transaction*)> callback,
bool acquireSingleBuffer = true) {
- mBlastBufferQueueAdapter->syncNextTransaction(callback, acquireSingleBuffer);
+ return mBlastBufferQueueAdapter->syncNextTransaction(callback, acquireSingleBuffer);
}
void stopContinuousSyncTransaction() {
mBlastBufferQueueAdapter->stopContinuousSyncTransaction();
}
+ void clearSyncTransaction() { mBlastBufferQueueAdapter->clearSyncTransaction(); }
+
int getWidth() { return mBlastBufferQueueAdapter->mSize.width; }
int getHeight() { return mBlastBufferQueueAdapter->mSize.height; }
@@ -175,30 +179,35 @@ protected:
BLASTBufferQueueTest() {
const ::testing::TestInfo* const testInfo =
::testing::UnitTest::GetInstance()->current_test_info();
- ALOGV("Begin test: %s.%s", testInfo->test_case_name(), testInfo->name());
+ ALOGD("Begin test: %s.%s", testInfo->test_case_name(), testInfo->name());
}
~BLASTBufferQueueTest() {
const ::testing::TestInfo* const testInfo =
::testing::UnitTest::GetInstance()->current_test_info();
- ALOGV("End test: %s.%s", testInfo->test_case_name(), testInfo->name());
+ ALOGD("End test: %s.%s", testInfo->test_case_name(), testInfo->name());
}
void SetUp() {
mComposer = ComposerService::getComposerService();
mClient = new SurfaceComposerClient();
- mDisplayToken = mClient->getInternalDisplayToken();
+ const auto ids = SurfaceComposerClient::getPhysicalDisplayIds();
+ ASSERT_FALSE(ids.empty());
+ // display 0 is picked as this test is not much display depedent
+ mDisplayToken = SurfaceComposerClient::getPhysicalDisplayToken(ids.front());
ASSERT_NE(nullptr, mDisplayToken.get());
Transaction t;
t.setDisplayLayerStack(mDisplayToken, ui::DEFAULT_LAYER_STACK);
t.apply();
t.clear();
- ui::DisplayMode mode;
- ASSERT_EQ(NO_ERROR, SurfaceComposerClient::getActiveDisplayMode(mDisplayToken, &mode));
- const ui::Size& resolution = mode.resolution;
+ ui::DisplayState displayState;
+ ASSERT_EQ(NO_ERROR, SurfaceComposerClient::getDisplayState(mDisplayToken, &displayState));
+ const ui::Size& resolution = displayState.layerStackSpaceRect;
mDisplayWidth = resolution.getWidth();
mDisplayHeight = resolution.getHeight();
+ ALOGD("Display: %dx%d orientation:%d", mDisplayWidth, mDisplayHeight,
+ displayState.orientation);
mSurfaceControl = mClient->createSurface(String8("TestSurface"), mDisplayWidth,
mDisplayHeight, PIXEL_FORMAT_RGBA_8888,
@@ -305,11 +314,12 @@ protected:
const sp<SyncScreenCaptureListener> captureListener = new SyncScreenCaptureListener();
binder::Status status = sf->captureDisplay(captureArgs, captureListener);
- if (status.transactionError() != NO_ERROR) {
- return status.transactionError();
+ status_t err = gui::aidl_utils::statusTFromBinderStatus(status);
+ if (err != NO_ERROR) {
+ return err;
}
captureResults = captureListener->waitForResults();
- return captureResults.result;
+ return fenceStatus(captureResults.fenceResult);
}
void queueBuffer(sp<IGraphicBufferProducer> igbp, uint8_t r, uint8_t g, uint8_t b,
@@ -1103,7 +1113,11 @@ TEST_F(BLASTBufferQueueTest, SyncNextTransactionOverwrite) {
ASSERT_NE(nullptr, adapter.getTransactionReadyCallback());
auto callback2 = [](Transaction*) {};
- adapter.syncNextTransaction(callback2);
+ ASSERT_FALSE(adapter.syncNextTransaction(callback2));
+
+ sp<IGraphicBufferProducer> igbProducer;
+ setUpProducer(adapter, igbProducer);
+ queueBuffer(igbProducer, 0, 255, 0, 0);
std::unique_lock<std::mutex> lock(mutex);
if (!receivedCallback) {
@@ -1115,6 +1129,37 @@ TEST_F(BLASTBufferQueueTest, SyncNextTransactionOverwrite) {
ASSERT_TRUE(receivedCallback);
}
+TEST_F(BLASTBufferQueueTest, ClearSyncTransaction) {
+ std::mutex mutex;
+ std::condition_variable callbackReceivedCv;
+ bool receivedCallback = false;
+
+ BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight);
+ ASSERT_EQ(nullptr, adapter.getTransactionReadyCallback());
+ auto callback = [&](Transaction*) {
+ std::unique_lock<std::mutex> lock(mutex);
+ receivedCallback = true;
+ callbackReceivedCv.notify_one();
+ };
+ adapter.syncNextTransaction(callback);
+ ASSERT_NE(nullptr, adapter.getTransactionReadyCallback());
+
+ adapter.clearSyncTransaction();
+
+ sp<IGraphicBufferProducer> igbProducer;
+ setUpProducer(adapter, igbProducer);
+ queueBuffer(igbProducer, 0, 255, 0, 0);
+
+ std::unique_lock<std::mutex> lock(mutex);
+ if (!receivedCallback) {
+ ASSERT_EQ(callbackReceivedCv.wait_for(lock, std::chrono::seconds(3)),
+ std::cv_status::timeout)
+ << "did not receive callback";
+ }
+
+ ASSERT_FALSE(receivedCallback);
+}
+
TEST_F(BLASTBufferQueueTest, SyncNextTransactionDropBuffer) {
uint8_t r = 255;
uint8_t g = 0;
@@ -1146,6 +1191,7 @@ TEST_F(BLASTBufferQueueTest, SyncNextTransactionDropBuffer) {
ASSERT_EQ(NO_ERROR, captureDisplay(mCaptureArgs, mCaptureResults));
ASSERT_NO_FATAL_FAILURE(
checkScreenCapture(r, g, b, {0, 0, (int32_t)mDisplayWidth, (int32_t)mDisplayHeight}));
+ sync.apply();
}
// This test will currently fail because the old surfacecontrol will steal the last presented buffer
diff --git a/libs/gui/tests/BufferItemConsumer_test.cpp b/libs/gui/tests/BufferItemConsumer_test.cpp
index fc6551c8e6..6880678050 100644
--- a/libs/gui/tests/BufferItemConsumer_test.cpp
+++ b/libs/gui/tests/BufferItemConsumer_test.cpp
@@ -68,7 +68,7 @@ class BufferItemConsumerTest : public ::testing::Test {
void HandleBufferFreed() {
std::lock_guard<std::mutex> lock(mMutex);
mFreedBufferCount++;
- ALOGV("HandleBufferFreed, mFreedBufferCount=%d", mFreedBufferCount);
+ ALOGD("HandleBufferFreed, mFreedBufferCount=%d", mFreedBufferCount);
}
void DequeueBuffer(int* outSlot) {
@@ -80,7 +80,7 @@ class BufferItemConsumerTest : public ::testing::Test {
nullptr, nullptr);
ASSERT_GE(ret, 0);
- ALOGV("dequeueBuffer: slot=%d", slot);
+ ALOGD("dequeueBuffer: slot=%d", slot);
if (ret & IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION) {
ret = mProducer->requestBuffer(slot, &mBuffers[slot]);
ASSERT_EQ(NO_ERROR, ret);
@@ -89,7 +89,7 @@ class BufferItemConsumerTest : public ::testing::Test {
}
void QueueBuffer(int slot) {
- ALOGV("enqueueBuffer: slot=%d", slot);
+ ALOGD("enqueueBuffer: slot=%d", slot);
IGraphicBufferProducer::QueueBufferInput bufferInput(
0ULL, true, HAL_DATASPACE_UNKNOWN, Rect::INVALID_RECT,
NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
@@ -104,12 +104,12 @@ class BufferItemConsumerTest : public ::testing::Test {
status_t ret = mBIC->acquireBuffer(&buffer, 0, false);
ASSERT_EQ(NO_ERROR, ret);
- ALOGV("acquireBuffer: slot=%d", buffer.mSlot);
+ ALOGD("acquireBuffer: slot=%d", buffer.mSlot);
*outSlot = buffer.mSlot;
}
void ReleaseBuffer(int slot) {
- ALOGV("releaseBuffer: slot=%d", slot);
+ ALOGD("releaseBuffer: slot=%d", slot);
BufferItem buffer;
buffer.mSlot = slot;
buffer.mGraphicBuffer = mBuffers[slot];
diff --git a/libs/gui/tests/BufferQueue_test.cpp b/libs/gui/tests/BufferQueue_test.cpp
index d1208ee5ae..2f1fd3e78f 100644
--- a/libs/gui/tests/BufferQueue_test.cpp
+++ b/libs/gui/tests/BufferQueue_test.cpp
@@ -49,14 +49,14 @@ protected:
BufferQueueTest() {
const ::testing::TestInfo* const testInfo =
::testing::UnitTest::GetInstance()->current_test_info();
- ALOGV("Begin test: %s.%s", testInfo->test_case_name(),
+ ALOGD("Begin test: %s.%s", testInfo->test_case_name(),
testInfo->name());
}
~BufferQueueTest() {
const ::testing::TestInfo* const testInfo =
::testing::UnitTest::GetInstance()->current_test_info();
- ALOGV("End test: %s.%s", testInfo->test_case_name(),
+ ALOGD("End test: %s.%s", testInfo->test_case_name(),
testInfo->name());
}
diff --git a/libs/gui/tests/CompositorTiming_test.cpp b/libs/gui/tests/CompositorTiming_test.cpp
new file mode 100644
index 0000000000..d8bb21d582
--- /dev/null
+++ b/libs/gui/tests/CompositorTiming_test.cpp
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <gtest/gtest.h>
+#include <gui/CompositorTiming.h>
+
+namespace android::test {
+namespace {
+
+constexpr nsecs_t kMillisecond = 1'000'000;
+constexpr nsecs_t kVsyncPeriod = 8'333'333;
+constexpr nsecs_t kVsyncPhase = -2'166'667;
+constexpr nsecs_t kIdealLatency = -kVsyncPhase;
+
+} // namespace
+
+TEST(CompositorTimingTest, InvalidVsyncPeriod) {
+ const nsecs_t vsyncDeadline = systemTime();
+ constexpr nsecs_t kInvalidVsyncPeriod = -1;
+
+ const gui::CompositorTiming timing(vsyncDeadline, kInvalidVsyncPeriod, kVsyncPhase,
+ kIdealLatency);
+
+ EXPECT_EQ(timing.deadline, 0);
+ EXPECT_EQ(timing.interval, gui::CompositorTiming::kDefaultVsyncPeriod);
+ EXPECT_EQ(timing.presentLatency, gui::CompositorTiming::kDefaultVsyncPeriod);
+}
+
+TEST(CompositorTimingTest, PresentLatencySnapping) {
+ for (nsecs_t presentDelay = 0, compositeTime = systemTime(); presentDelay < 10 * kVsyncPeriod;
+ presentDelay += kMillisecond, compositeTime += kVsyncPeriod) {
+ const nsecs_t presentLatency = kIdealLatency + presentDelay;
+ const nsecs_t vsyncDeadline = compositeTime + presentLatency + kVsyncPeriod;
+
+ const gui::CompositorTiming timing(vsyncDeadline, kVsyncPeriod, kVsyncPhase,
+ presentLatency);
+
+ EXPECT_EQ(timing.deadline, compositeTime + presentDelay + kVsyncPeriod);
+ EXPECT_EQ(timing.interval, kVsyncPeriod);
+
+ // The presentDelay should be rounded to a multiple of the VSYNC period, such that the
+ // remainder (presentLatency % interval) always evaluates to the VSYNC phase offset.
+ EXPECT_GE(timing.presentLatency, kIdealLatency);
+ EXPECT_EQ(timing.presentLatency % timing.interval, kIdealLatency);
+ }
+}
+
+} // namespace android::test
diff --git a/libs/gui/tests/CpuConsumer_test.cpp b/libs/gui/tests/CpuConsumer_test.cpp
index 00e32d9124..0a14afac55 100644
--- a/libs/gui/tests/CpuConsumer_test.cpp
+++ b/libs/gui/tests/CpuConsumer_test.cpp
@@ -62,7 +62,7 @@ protected:
const ::testing::TestInfo* const test_info =
::testing::UnitTest::GetInstance()->current_test_info();
CpuConsumerTestParams params = GetParam();
- ALOGV("** Starting test %s (%d x %d, %d, 0x%x)",
+ ALOGD("** Starting test %s (%d x %d, %d, 0x%x)",
test_info->name(),
params.width, params.height,
params.maxLockedBuffers, params.format);
@@ -582,7 +582,7 @@ TEST_P(CpuConsumerTest, FromCpuManyInQueue) {
uint32_t stride[numInQueue];
for (int i = 0; i < numInQueue; i++) {
- ALOGV("Producing frame %d", i);
+ ALOGD("Producing frame %d", i);
ASSERT_NO_FATAL_FAILURE(produceOneFrame(mANW, params, time[i],
&stride[i]));
}
@@ -590,7 +590,7 @@ TEST_P(CpuConsumerTest, FromCpuManyInQueue) {
// Consume
for (int i = 0; i < numInQueue; i++) {
- ALOGV("Consuming frame %d", i);
+ ALOGD("Consuming frame %d", i);
CpuConsumer::LockedBuffer b;
err = mCC->lockNextBuffer(&b);
ASSERT_NO_ERROR(err, "getNextBuffer error: ");
@@ -624,7 +624,7 @@ TEST_P(CpuConsumerTest, FromCpuLockMax) {
uint32_t stride;
for (int i = 0; i < params.maxLockedBuffers + 1; i++) {
- ALOGV("Producing frame %d", i);
+ ALOGD("Producing frame %d", i);
ASSERT_NO_FATAL_FAILURE(produceOneFrame(mANW, params, time,
&stride));
}
@@ -633,7 +633,7 @@ TEST_P(CpuConsumerTest, FromCpuLockMax) {
std::vector<CpuConsumer::LockedBuffer> b(params.maxLockedBuffers);
for (int i = 0; i < params.maxLockedBuffers; i++) {
- ALOGV("Locking frame %d", i);
+ ALOGD("Locking frame %d", i);
err = mCC->lockNextBuffer(&b[i]);
ASSERT_NO_ERROR(err, "getNextBuffer error: ");
@@ -647,16 +647,16 @@ TEST_P(CpuConsumerTest, FromCpuLockMax) {
checkAnyBuffer(b[i], GetParam().format);
}
- ALOGV("Locking frame %d (too many)", params.maxLockedBuffers);
+ ALOGD("Locking frame %d (too many)", params.maxLockedBuffers);
CpuConsumer::LockedBuffer bTooMuch;
err = mCC->lockNextBuffer(&bTooMuch);
ASSERT_TRUE(err == NOT_ENOUGH_DATA) << "Allowing too many locks";
- ALOGV("Unlocking frame 0");
+ ALOGD("Unlocking frame 0");
err = mCC->unlockBuffer(b[0]);
ASSERT_NO_ERROR(err, "Could not unlock buffer 0: ");
- ALOGV("Locking frame %d (should work now)", params.maxLockedBuffers);
+ ALOGD("Locking frame %d (should work now)", params.maxLockedBuffers);
err = mCC->lockNextBuffer(&bTooMuch);
ASSERT_NO_ERROR(err, "Did not allow new lock after unlock");
@@ -669,11 +669,11 @@ TEST_P(CpuConsumerTest, FromCpuLockMax) {
checkAnyBuffer(bTooMuch, GetParam().format);
- ALOGV("Unlocking extra buffer");
+ ALOGD("Unlocking extra buffer");
err = mCC->unlockBuffer(bTooMuch);
ASSERT_NO_ERROR(err, "Could not unlock extra buffer: ");
- ALOGV("Locking frame %d (no more available)", params.maxLockedBuffers + 1);
+ ALOGD("Locking frame %d (no more available)", params.maxLockedBuffers + 1);
err = mCC->lockNextBuffer(&b[0]);
ASSERT_EQ(BAD_VALUE, err) << "Not out of buffers somehow";
diff --git a/libs/gui/tests/DisplayEventStructLayout_test.cpp b/libs/gui/tests/DisplayEventStructLayout_test.cpp
index da88463d63..3949d70aac 100644
--- a/libs/gui/tests/DisplayEventStructLayout_test.cpp
+++ b/libs/gui/tests/DisplayEventStructLayout_test.cpp
@@ -35,6 +35,7 @@ TEST(DisplayEventStructLayoutTest, TestEventAlignment) {
CHECK_OFFSET(DisplayEventReceiver::Event::VSync, count, 0);
CHECK_OFFSET(DisplayEventReceiver::Event::VSync, vsyncData.frameInterval, 8);
CHECK_OFFSET(DisplayEventReceiver::Event::VSync, vsyncData.preferredFrameTimelineIndex, 16);
+ CHECK_OFFSET(DisplayEventReceiver::Event::VSync, vsyncData.frameTimelinesLength, 20);
CHECK_OFFSET(DisplayEventReceiver::Event::VSync, vsyncData.frameTimelines, 24);
CHECK_OFFSET(DisplayEventReceiver::Event::VSync, vsyncData.frameTimelines[0].vsyncId, 24);
CHECK_OFFSET(DisplayEventReceiver::Event::VSync, vsyncData.frameTimelines[0].deadlineTimestamp,
@@ -44,16 +45,16 @@ TEST(DisplayEventStructLayoutTest, TestEventAlignment) {
// Also test the offsets of the last frame timeline. A loop is not used because the non-const
// index cannot be used in static_assert.
const int lastFrameTimelineOffset = /* Start of array */ 24 +
- (VsyncEventData::kFrameTimelinesLength - 1) * /* Size of FrameTimeline */ 24;
+ (VsyncEventData::kFrameTimelinesCapacity - 1) * /* Size of FrameTimeline */ 24;
CHECK_OFFSET(DisplayEventReceiver::Event::VSync,
- vsyncData.frameTimelines[VsyncEventData::kFrameTimelinesLength - 1].vsyncId,
+ vsyncData.frameTimelines[VsyncEventData::kFrameTimelinesCapacity - 1].vsyncId,
lastFrameTimelineOffset);
CHECK_OFFSET(DisplayEventReceiver::Event::VSync,
- vsyncData.frameTimelines[VsyncEventData::kFrameTimelinesLength - 1]
+ vsyncData.frameTimelines[VsyncEventData::kFrameTimelinesCapacity - 1]
.deadlineTimestamp,
lastFrameTimelineOffset + 8);
CHECK_OFFSET(DisplayEventReceiver::Event::VSync,
- vsyncData.frameTimelines[VsyncEventData::kFrameTimelinesLength - 1]
+ vsyncData.frameTimelines[VsyncEventData::kFrameTimelinesCapacity - 1]
.expectedPresentationTime,
lastFrameTimelineOffset + 16);
diff --git a/libs/gui/tests/DisplayedContentSampling_test.cpp b/libs/gui/tests/DisplayedContentSampling_test.cpp
index b647aaba8f..0a2750a4dd 100644
--- a/libs/gui/tests/DisplayedContentSampling_test.cpp
+++ b/libs/gui/tests/DisplayedContentSampling_test.cpp
@@ -32,7 +32,10 @@ protected:
void SetUp() {
mComposerClient = new SurfaceComposerClient;
ASSERT_EQ(OK, mComposerClient->initCheck());
- mDisplayToken = mComposerClient->getInternalDisplayToken();
+ const auto ids = SurfaceComposerClient::getPhysicalDisplayIds();
+ ASSERT_FALSE(ids.empty());
+ // display 0 is picked for now, can extend to support all displays if needed
+ mDisplayToken = SurfaceComposerClient::getPhysicalDisplayToken(ids.front());
ASSERT_TRUE(mDisplayToken);
}
diff --git a/libs/gui/tests/EndToEndNativeInputTest.cpp b/libs/gui/tests/EndToEndNativeInputTest.cpp
index 2637f59b5e..4ec7a06cb8 100644
--- a/libs/gui/tests/EndToEndNativeInputTest.cpp
+++ b/libs/gui/tests/EndToEndNativeInputTest.cpp
@@ -164,7 +164,7 @@ public:
void assertFocusChange(bool hasFocus) {
InputEvent *ev = consumeEvent();
ASSERT_NE(ev, nullptr);
- ASSERT_EQ(AINPUT_EVENT_TYPE_FOCUS, ev->getType());
+ ASSERT_EQ(InputEventType::FOCUS, ev->getType());
FocusEvent *focusEvent = static_cast<FocusEvent *>(ev);
EXPECT_EQ(hasFocus, focusEvent->getHasFocus());
}
@@ -172,7 +172,7 @@ public:
void expectTap(int x, int y) {
InputEvent* ev = consumeEvent();
ASSERT_NE(ev, nullptr);
- ASSERT_EQ(AINPUT_EVENT_TYPE_MOTION, ev->getType());
+ ASSERT_EQ(InputEventType::MOTION, ev->getType());
MotionEvent* mev = static_cast<MotionEvent*>(ev);
EXPECT_EQ(AMOTION_EVENT_ACTION_DOWN, mev->getAction());
EXPECT_EQ(x, mev->getX(0));
@@ -181,7 +181,7 @@ public:
ev = consumeEvent();
ASSERT_NE(ev, nullptr);
- ASSERT_EQ(AINPUT_EVENT_TYPE_MOTION, ev->getType());
+ ASSERT_EQ(InputEventType::MOTION, ev->getType());
mev = static_cast<MotionEvent*>(ev);
EXPECT_EQ(AMOTION_EVENT_ACTION_UP, mev->getAction());
EXPECT_EQ(0, mev->getFlags() & VERIFIED_MOTION_EVENT_FLAGS);
@@ -190,7 +190,7 @@ public:
void expectTapWithFlag(int x, int y, int32_t flags) {
InputEvent *ev = consumeEvent();
ASSERT_NE(ev, nullptr);
- ASSERT_EQ(AINPUT_EVENT_TYPE_MOTION, ev->getType());
+ ASSERT_EQ(InputEventType::MOTION, ev->getType());
MotionEvent *mev = static_cast<MotionEvent *>(ev);
EXPECT_EQ(AMOTION_EVENT_ACTION_DOWN, mev->getAction());
EXPECT_EQ(x, mev->getX(0));
@@ -199,7 +199,7 @@ public:
ev = consumeEvent();
ASSERT_NE(ev, nullptr);
- ASSERT_EQ(AINPUT_EVENT_TYPE_MOTION, ev->getType());
+ ASSERT_EQ(InputEventType::MOTION, ev->getType());
mev = static_cast<MotionEvent *>(ev);
EXPECT_EQ(AMOTION_EVENT_ACTION_UP, mev->getAction());
EXPECT_EQ(flags, mev->getFlags() & flags);
@@ -208,7 +208,7 @@ public:
void expectTapInDisplayCoordinates(int displayX, int displayY) {
InputEvent *ev = consumeEvent();
ASSERT_NE(ev, nullptr);
- ASSERT_EQ(AINPUT_EVENT_TYPE_MOTION, ev->getType());
+ ASSERT_EQ(InputEventType::MOTION, ev->getType());
MotionEvent *mev = static_cast<MotionEvent *>(ev);
EXPECT_EQ(AMOTION_EVENT_ACTION_DOWN, mev->getAction());
const PointerCoords &coords = *mev->getRawPointerCoords(0 /*pointerIndex*/);
@@ -218,7 +218,7 @@ public:
ev = consumeEvent();
ASSERT_NE(ev, nullptr);
- ASSERT_EQ(AINPUT_EVENT_TYPE_MOTION, ev->getType());
+ ASSERT_EQ(InputEventType::MOTION, ev->getType());
mev = static_cast<MotionEvent *>(ev);
EXPECT_EQ(AMOTION_EVENT_ACTION_UP, mev->getAction());
EXPECT_EQ(0, mev->getFlags() & VERIFIED_MOTION_EVENT_FLAGS);
@@ -227,7 +227,7 @@ public:
void expectKey(uint32_t keycode) {
InputEvent *ev = consumeEvent();
ASSERT_NE(ev, nullptr);
- ASSERT_EQ(AINPUT_EVENT_TYPE_KEY, ev->getType());
+ ASSERT_EQ(InputEventType::KEY, ev->getType());
KeyEvent *keyEvent = static_cast<KeyEvent *>(ev);
EXPECT_EQ(AMOTION_EVENT_ACTION_DOWN, keyEvent->getAction());
EXPECT_EQ(keycode, keyEvent->getKeyCode());
@@ -235,7 +235,7 @@ public:
ev = consumeEvent();
ASSERT_NE(ev, nullptr);
- ASSERT_EQ(AINPUT_EVENT_TYPE_KEY, ev->getType());
+ ASSERT_EQ(InputEventType::KEY, ev->getType());
keyEvent = static_cast<KeyEvent *>(ev);
EXPECT_EQ(AMOTION_EVENT_ACTION_UP, keyEvent->getAction());
EXPECT_EQ(keycode, keyEvent->getKeyCode());
@@ -272,8 +272,6 @@ public:
FocusRequest request;
request.token = mInputInfo.token;
request.windowName = mInputInfo.name;
- request.focusedToken = nullptr;
- request.focusedWindowName = "";
request.timestamp = systemTime(SYSTEM_TIME_MONOTONIC);
request.displayId = displayId;
t.setFocusedWindow(request);
@@ -360,8 +358,10 @@ public:
void SetUp() {
mComposerClient = new SurfaceComposerClient;
ASSERT_EQ(NO_ERROR, mComposerClient->initCheck());
-
- const auto display = mComposerClient->getInternalDisplayToken();
+ const auto ids = SurfaceComposerClient::getPhysicalDisplayIds();
+ ASSERT_FALSE(ids.empty());
+ // display 0 is picked for now, can extend to support all displays if needed
+ const auto display = SurfaceComposerClient::getPhysicalDisplayToken(ids.front());
ASSERT_NE(display, nullptr);
ui::DisplayMode mode;
@@ -510,6 +510,22 @@ TEST_F(InputSurfacesTest, input_respects_surface_insets) {
bgSurface->expectTap(1, 1);
}
+TEST_F(InputSurfacesTest, input_respects_surface_insets_with_replaceTouchableRegionWithCrop) {
+ std::unique_ptr<InputSurface> bgSurface = makeSurface(100, 100);
+ std::unique_ptr<InputSurface> fgSurface = makeSurface(100, 100);
+ bgSurface->showAt(100, 100);
+
+ fgSurface->mInputInfo.surfaceInset = 5;
+ fgSurface->mInputInfo.replaceTouchableRegionWithCrop = true;
+ fgSurface->showAt(100, 100);
+
+ injectTap(106, 106);
+ fgSurface->expectTap(1, 1);
+
+ injectTap(101, 101);
+ bgSurface->expectTap(1, 1);
+}
+
// Ensure a surface whose insets are cropped, handles the touch offset correctly. ref:b/120413463
TEST_F(InputSurfacesTest, input_respects_cropped_surface_insets) {
std::unique_ptr<InputSurface> parentSurface = makeSurface(100, 100);
@@ -612,7 +628,7 @@ TEST_F(InputSurfacesTest, input_respects_scaled_touchable_region_overflow) {
// Expect no crash for overflow.
injectTap(12, 24);
- fgSurface->expectTap(6, 12);
+ bgSurface->expectTap(12, 24);
}
// Ensure we ignore transparent region when getting screen bounds when positioning input frame.
@@ -1219,32 +1235,6 @@ TEST_F(MultiDisplayTests, virtual_display_receives_input) {
surface->expectKey(AKEYCODE_V);
}
-/**
- * When multiple DisplayDevices are mapped to the same layerStack, use the configuration for the
- * display that can receive input.
- */
-TEST_F(MultiDisplayTests, many_to_one_display_mapping) {
- ui::LayerStack layerStack = ui::LayerStack::fromValue(42);
- createDisplay(1000, 1000, false /*isSecure*/, layerStack, false /*receivesInput*/,
- 100 /*offsetX*/, 100 /*offsetY*/);
- createDisplay(1000, 1000, false /*isSecure*/, layerStack, true /*receivesInput*/,
- 200 /*offsetX*/, 200 /*offsetY*/);
- createDisplay(1000, 1000, false /*isSecure*/, layerStack, false /*receivesInput*/,
- 300 /*offsetX*/, 300 /*offsetY*/);
- std::unique_ptr<InputSurface> surface = makeSurface(100, 100);
- surface->doTransaction([&](auto &t, auto &sc) { t.setLayerStack(sc, layerStack); });
- surface->showAt(10, 10);
-
- // Input injection happens in logical display coordinates.
- injectTapOnDisplay(11, 11, layerStack.id);
- // Expect that the display transform for the display that receives input was used.
- surface->expectTapInDisplayCoordinates(211, 211);
-
- surface->requestFocus(layerStack.id);
- surface->assertFocusChange(true);
- injectKeyOnDisplay(AKEYCODE_V, layerStack.id);
-}
-
TEST_F(MultiDisplayTests, drop_input_for_secure_layer_on_nonsecure_display) {
ui::LayerStack layerStack = ui::LayerStack::fromValue(42);
createDisplay(1000, 1000, false /*isSecure*/, layerStack);
diff --git a/libs/gui/tests/GLTest.cpp b/libs/gui/tests/GLTest.cpp
index 449cbf9f75..e5f4aaa999 100644
--- a/libs/gui/tests/GLTest.cpp
+++ b/libs/gui/tests/GLTest.cpp
@@ -31,7 +31,7 @@ static int abs(int value) {
void GLTest::SetUp() {
const ::testing::TestInfo* const testInfo =
::testing::UnitTest::GetInstance()->current_test_info();
- ALOGV("Begin test: %s.%s", testInfo->test_case_name(), testInfo->name());
+ ALOGD("Begin test: %s.%s", testInfo->test_case_name(), testInfo->name());
mEglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
ASSERT_EQ(EGL_SUCCESS, eglGetError());
@@ -135,7 +135,7 @@ void GLTest::TearDown() {
const ::testing::TestInfo* const testInfo =
::testing::UnitTest::GetInstance()->current_test_info();
- ALOGV("End test: %s.%s", testInfo->test_case_name(), testInfo->name());
+ ALOGD("End test: %s.%s", testInfo->test_case_name(), testInfo->name());
}
EGLint const* GLTest::getConfigAttribs() {
diff --git a/libs/gui/tests/IGraphicBufferProducer_test.cpp b/libs/gui/tests/IGraphicBufferProducer_test.cpp
index 3427731fff..e6cb89cb83 100644
--- a/libs/gui/tests/IGraphicBufferProducer_test.cpp
+++ b/libs/gui/tests/IGraphicBufferProducer_test.cpp
@@ -84,7 +84,7 @@ protected:
virtual void SetUp() {
const ::testing::TestInfo* const testInfo =
::testing::UnitTest::GetInstance()->current_test_info();
- ALOGV("Begin test: %s.%s", testInfo->test_case_name(),
+ ALOGD("Begin test: %s.%s", testInfo->test_case_name(),
testInfo->name());
mMC = new MockConsumer;
@@ -114,7 +114,7 @@ protected:
virtual void TearDown() {
const ::testing::TestInfo* const testInfo =
::testing::UnitTest::GetInstance()->current_test_info();
- ALOGV("End test: %s.%s", testInfo->test_case_name(),
+ ALOGD("End test: %s.%s", testInfo->test_case_name(),
testInfo->name());
}
diff --git a/libs/gui/tests/RegionSampling_test.cpp b/libs/gui/tests/RegionSampling_test.cpp
index c9106bed4c..b18b544257 100644
--- a/libs/gui/tests/RegionSampling_test.cpp
+++ b/libs/gui/tests/RegionSampling_test.cpp
@@ -19,14 +19,16 @@
#include <android/gui/BnRegionSamplingListener.h>
#include <binder/ProcessState.h>
+#include <gui/AidlStatusUtil.h>
#include <gui/DisplayEventReceiver.h>
#include <gui/ISurfaceComposer.h>
#include <gui/Surface.h>
#include <gui/SurfaceComposerClient.h>
-#include <private/gui/ComposerService.h>
+#include <private/gui/ComposerServiceAIDL.h>
#include <utils/Looper.h>
using namespace std::chrono_literals;
+using android::gui::aidl_utils::statusTFromBinderStatus;
namespace android::test {
@@ -242,24 +244,33 @@ protected:
};
TEST_F(RegionSamplingTest, invalidLayerHandle_doesNotCrash) {
- sp<ISurfaceComposer> composer = ComposerService::getComposerService();
+ sp<gui::ISurfaceComposer> composer = ComposerServiceAIDL::getComposerService();
sp<Listener> listener = new Listener();
- const Rect sampleArea{100, 100, 200, 200};
+ gui::ARect sampleArea;
+ sampleArea.left = 100;
+ sampleArea.top = 100;
+ sampleArea.right = 200;
+ sampleArea.bottom = 200;
// Passing in composer service as the layer handle should not crash, we'll
// treat it as a layer that no longer exists and silently allow sampling to
// occur.
- status_t status = composer->addRegionSamplingListener(sampleArea,
- IInterface::asBinder(composer), listener);
- ASSERT_EQ(NO_ERROR, status);
+ binder::Status status =
+ composer->addRegionSamplingListener(sampleArea, IInterface::asBinder(composer),
+ listener);
+ ASSERT_EQ(NO_ERROR, statusTFromBinderStatus(status));
composer->removeRegionSamplingListener(listener);
}
TEST_F(RegionSamplingTest, DISABLED_CollectsLuma) {
fill_render(rgba_green);
- sp<ISurfaceComposer> composer = ComposerService::getComposerService();
+ sp<gui::ISurfaceComposer> composer = ComposerServiceAIDL::getComposerService();
sp<Listener> listener = new Listener();
- const Rect sampleArea{100, 100, 200, 200};
+ gui::ARect sampleArea;
+ sampleArea.left = 100;
+ sampleArea.top = 100;
+ sampleArea.right = 200;
+ sampleArea.bottom = 200;
composer->addRegionSamplingListener(sampleArea, mTopLayer->getHandle(), listener);
EXPECT_TRUE(listener->wait_event(300ms)) << "timed out waiting for luma event to be received";
@@ -271,9 +282,13 @@ TEST_F(RegionSamplingTest, DISABLED_CollectsLuma) {
TEST_F(RegionSamplingTest, DISABLED_CollectsChangingLuma) {
fill_render(rgba_green);
- sp<ISurfaceComposer> composer = ComposerService::getComposerService();
+ sp<gui::ISurfaceComposer> composer = ComposerServiceAIDL::getComposerService();
sp<Listener> listener = new Listener();
- const Rect sampleArea{100, 100, 200, 200};
+ gui::ARect sampleArea;
+ sampleArea.left = 100;
+ sampleArea.top = 100;
+ sampleArea.right = 200;
+ sampleArea.bottom = 200;
composer->addRegionSamplingListener(sampleArea, mTopLayer->getHandle(), listener);
EXPECT_TRUE(listener->wait_event(300ms)) << "timed out waiting for luma event to be received";
@@ -291,13 +306,21 @@ TEST_F(RegionSamplingTest, DISABLED_CollectsChangingLuma) {
TEST_F(RegionSamplingTest, DISABLED_CollectsLumaFromTwoRegions) {
fill_render(rgba_green);
- sp<ISurfaceComposer> composer = ComposerService::getComposerService();
+ sp<gui::ISurfaceComposer> composer = ComposerServiceAIDL::getComposerService();
sp<Listener> greenListener = new Listener();
- const Rect greenSampleArea{100, 100, 200, 200};
+ gui::ARect greenSampleArea;
+ greenSampleArea.left = 100;
+ greenSampleArea.top = 100;
+ greenSampleArea.right = 200;
+ greenSampleArea.bottom = 200;
composer->addRegionSamplingListener(greenSampleArea, mTopLayer->getHandle(), greenListener);
sp<Listener> grayListener = new Listener();
- const Rect graySampleArea{500, 100, 600, 200};
+ gui::ARect graySampleArea;
+ graySampleArea.left = 500;
+ graySampleArea.top = 100;
+ graySampleArea.right = 600;
+ graySampleArea.bottom = 200;
composer->addRegionSamplingListener(graySampleArea, mTopLayer->getHandle(), grayListener);
EXPECT_TRUE(grayListener->wait_event(300ms))
@@ -312,29 +335,49 @@ TEST_F(RegionSamplingTest, DISABLED_CollectsLumaFromTwoRegions) {
}
TEST_F(RegionSamplingTest, DISABLED_TestIfInvalidInputParameters) {
- sp<ISurfaceComposer> composer = ComposerService::getComposerService();
+ sp<gui::ISurfaceComposer> composer = ComposerServiceAIDL::getComposerService();
sp<Listener> listener = new Listener();
- const Rect sampleArea{100, 100, 200, 200};
+
+ gui::ARect invalidRect;
+ invalidRect.left = Rect::INVALID_RECT.left;
+ invalidRect.top = Rect::INVALID_RECT.top;
+ invalidRect.right = Rect::INVALID_RECT.right;
+ invalidRect.bottom = Rect::INVALID_RECT.bottom;
+
+ gui::ARect sampleArea;
+ sampleArea.left = 100;
+ sampleArea.top = 100;
+ sampleArea.right = 200;
+ sampleArea.bottom = 200;
// Invalid input sampleArea
EXPECT_EQ(BAD_VALUE,
- composer->addRegionSamplingListener(Rect::INVALID_RECT, mTopLayer->getHandle(),
- listener));
+ statusTFromBinderStatus(composer->addRegionSamplingListener(invalidRect,
+ mTopLayer->getHandle(),
+ listener)));
listener->reset();
// Invalid input binder
- EXPECT_EQ(NO_ERROR, composer->addRegionSamplingListener(sampleArea, NULL, listener));
+ EXPECT_EQ(NO_ERROR,
+ statusTFromBinderStatus(
+ composer->addRegionSamplingListener(sampleArea, NULL, listener)));
// Invalid input listener
EXPECT_EQ(BAD_VALUE,
- composer->addRegionSamplingListener(sampleArea, mTopLayer->getHandle(), NULL));
- EXPECT_EQ(BAD_VALUE, composer->removeRegionSamplingListener(NULL));
+ statusTFromBinderStatus(composer->addRegionSamplingListener(sampleArea,
+ mTopLayer->getHandle(),
+ NULL)));
+ EXPECT_EQ(BAD_VALUE, statusTFromBinderStatus(composer->removeRegionSamplingListener(NULL)));
// remove the listener
composer->removeRegionSamplingListener(listener);
}
TEST_F(RegionSamplingTest, DISABLED_TestCallbackAfterRemoveListener) {
fill_render(rgba_green);
- sp<ISurfaceComposer> composer = ComposerService::getComposerService();
+ sp<gui::ISurfaceComposer> composer = ComposerServiceAIDL::getComposerService();
sp<Listener> listener = new Listener();
- const Rect sampleArea{100, 100, 200, 200};
+ gui::ARect sampleArea;
+ sampleArea.left = 100;
+ sampleArea.top = 100;
+ sampleArea.right = 200;
+ sampleArea.bottom = 200;
composer->addRegionSamplingListener(sampleArea, mTopLayer->getHandle(), listener);
fill_render(rgba_green);
@@ -349,13 +392,18 @@ TEST_F(RegionSamplingTest, DISABLED_TestCallbackAfterRemoveListener) {
}
TEST_F(RegionSamplingTest, DISABLED_CollectsLumaFromMovingLayer) {
- sp<ISurfaceComposer> composer = ComposerService::getComposerService();
+ sp<gui::ISurfaceComposer> composer = ComposerServiceAIDL::getComposerService();
sp<Listener> listener = new Listener();
Rect sampleArea{100, 100, 200, 200};
+ gui::ARect sampleAreaA;
+ sampleAreaA.left = sampleArea.left;
+ sampleAreaA.top = sampleArea.top;
+ sampleAreaA.right = sampleArea.right;
+ sampleAreaA.bottom = sampleArea.bottom;
// Test: listener in (100, 100). See layer before move, no layer after move.
fill_render(rgba_blue);
- composer->addRegionSamplingListener(sampleArea, mTopLayer->getHandle(), listener);
+ composer->addRegionSamplingListener(sampleAreaA, mTopLayer->getHandle(), listener);
EXPECT_TRUE(listener->wait_event(300ms)) << "timed out waiting for luma event to be received";
EXPECT_NEAR(listener->luma(), luma_blue, error_margin);
listener->reset();
@@ -367,7 +415,11 @@ TEST_F(RegionSamplingTest, DISABLED_CollectsLumaFromMovingLayer) {
// Test: listener offset to (600, 600). No layer before move, see layer after move.
fill_render(rgba_green);
sampleArea.offsetTo(600, 600);
- composer->addRegionSamplingListener(sampleArea, mTopLayer->getHandle(), listener);
+ sampleAreaA.left = sampleArea.left;
+ sampleAreaA.top = sampleArea.top;
+ sampleAreaA.right = sampleArea.right;
+ sampleAreaA.bottom = sampleArea.bottom;
+ composer->addRegionSamplingListener(sampleAreaA, mTopLayer->getHandle(), listener);
EXPECT_TRUE(listener->wait_event(300ms)) << "timed out waiting for luma event to be received";
EXPECT_NEAR(listener->luma(), luma_gray, error_margin);
listener->reset();
diff --git a/libs/gui/tests/SamplingDemo.cpp b/libs/gui/tests/SamplingDemo.cpp
index a083a228a6..f98437b4f8 100644
--- a/libs/gui/tests/SamplingDemo.cpp
+++ b/libs/gui/tests/SamplingDemo.cpp
@@ -26,7 +26,7 @@
#include <gui/ISurfaceComposer.h>
#include <gui/SurfaceComposerClient.h>
#include <gui/SurfaceControl.h>
-#include <private/gui/ComposerService.h>
+#include <private/gui/ComposerServiceAIDL.h>
#include <utils/Trace.h>
using namespace std::chrono_literals;
@@ -121,10 +121,22 @@ int main(int, const char**) {
const Rect backButtonArea{200, 1606, 248, 1654};
sp<android::Button> backButton = new android::Button("BackButton", backButtonArea);
- sp<ISurfaceComposer> composer = ComposerService::getComposerService();
- composer->addRegionSamplingListener(homeButtonArea, homeButton->getStopLayerHandle(),
+ gui::ARect homeButtonAreaA;
+ homeButtonAreaA.left = 490;
+ homeButtonAreaA.top = 1606;
+ homeButtonAreaA.right = 590;
+ homeButtonAreaA.bottom = 1654;
+
+ gui::ARect backButtonAreaA;
+ backButtonAreaA.left = 200;
+ backButtonAreaA.top = 1606;
+ backButtonAreaA.right = 248;
+ backButtonAreaA.bottom = 1654;
+
+ sp<gui::ISurfaceComposer> composer = ComposerServiceAIDL::getComposerService();
+ composer->addRegionSamplingListener(homeButtonAreaA, homeButton->getStopLayerHandle(),
homeButton);
- composer->addRegionSamplingListener(backButtonArea, backButton->getStopLayerHandle(),
+ composer->addRegionSamplingListener(backButtonAreaA, backButton->getStopLayerHandle(),
backButton);
ProcessState::self()->startThreadPool();
diff --git a/libs/gui/tests/StreamSplitter_test.cpp b/libs/gui/tests/StreamSplitter_test.cpp
index b65cddaea3..2f14924a15 100644
--- a/libs/gui/tests/StreamSplitter_test.cpp
+++ b/libs/gui/tests/StreamSplitter_test.cpp
@@ -36,14 +36,14 @@ protected:
StreamSplitterTest() {
const ::testing::TestInfo* const testInfo =
::testing::UnitTest::GetInstance()->current_test_info();
- ALOGV("Begin test: %s.%s", testInfo->test_case_name(),
+ ALOGD("Begin test: %s.%s", testInfo->test_case_name(),
testInfo->name());
}
~StreamSplitterTest() {
const ::testing::TestInfo* const testInfo =
::testing::UnitTest::GetInstance()->current_test_info();
- ALOGV("End test: %s.%s", testInfo->test_case_name(),
+ ALOGD("End test: %s.%s", testInfo->test_case_name(),
testInfo->name());
}
};
diff --git a/libs/gui/tests/SurfaceTextureClient_test.cpp b/libs/gui/tests/SurfaceTextureClient_test.cpp
index c7458a3755..82b66972d9 100644
--- a/libs/gui/tests/SurfaceTextureClient_test.cpp
+++ b/libs/gui/tests/SurfaceTextureClient_test.cpp
@@ -42,7 +42,7 @@ protected:
virtual void SetUp() {
const ::testing::TestInfo* const testInfo =
::testing::UnitTest::GetInstance()->current_test_info();
- ALOGV("Begin test: %s.%s", testInfo->test_case_name(),
+ ALOGD("Begin test: %s.%s", testInfo->test_case_name(),
testInfo->name());
sp<IGraphicBufferProducer> producer;
@@ -99,7 +99,7 @@ protected:
const ::testing::TestInfo* const testInfo =
::testing::UnitTest::GetInstance()->current_test_info();
- ALOGV("End test: %s.%s", testInfo->test_case_name(),
+ ALOGD("End test: %s.%s", testInfo->test_case_name(),
testInfo->name());
}
diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp
index cb977f04c9..c1b67b4396 100644
--- a/libs/gui/tests/Surface_test.cpp
+++ b/libs/gui/tests/Surface_test.cpp
@@ -24,6 +24,7 @@
#include <android/hardware/configstore/1.0/ISurfaceFlingerConfigs.h>
#include <binder/ProcessState.h>
#include <configstore/Utils.h>
+#include <gui/AidlStatusUtil.h>
#include <gui/BufferItemConsumer.h>
#include <gui/IProducerListener.h>
#include <gui/ISurfaceComposer.h>
@@ -212,11 +213,12 @@ protected:
const sp<SyncScreenCaptureListener> captureListener = new SyncScreenCaptureListener();
binder::Status status = sf->captureDisplay(captureArgs, captureListener);
- if (status.transactionError() != NO_ERROR) {
- return status.transactionError();
+ status_t err = gui::aidl_utils::statusTFromBinderStatus(status);
+ if (err != NO_ERROR) {
+ return err;
}
captureResults = captureListener->waitForResults();
- return captureResults.result;
+ return fenceStatus(captureResults.fenceResult);
}
sp<Surface> mSurface;
@@ -261,7 +263,10 @@ TEST_F(SurfaceTest, ScreenshotsOfProtectedBuffersDontSucceed) {
sp<ANativeWindow> anw(mSurface);
// Verify the screenshot works with no protected buffers.
- const sp<IBinder> display = ComposerServiceAIDL::getInstance().getInternalDisplayToken();
+ const auto ids = SurfaceComposerClient::getPhysicalDisplayIds();
+ ASSERT_FALSE(ids.empty());
+ // display 0 is picked for now, can extend to support all displays if needed
+ const sp<IBinder> display = SurfaceComposerClient::getPhysicalDisplayToken(ids.front());
ASSERT_FALSE(display == nullptr);
DisplayCaptureArgs captureArgs;
@@ -690,278 +695,257 @@ public:
mSupportsPresent = supportsPresent;
}
- sp<ISurfaceComposerClient> createConnection() override { return nullptr; }
- sp<IDisplayEventConnection> createDisplayEventConnection(
- ISurfaceComposer::VsyncSource, ISurfaceComposer::EventRegistrationFlags) override {
- return nullptr;
- }
- status_t setTransactionState(const FrameTimelineInfo& /*frameTimelineInfo*/,
- const Vector<ComposerState>& /*state*/,
- const Vector<DisplayState>& /*displays*/, uint32_t /*flags*/,
- const sp<IBinder>& /*applyToken*/,
- const InputWindowCommands& /*inputWindowCommands*/,
- int64_t /*desiredPresentTime*/, bool /*isAutoTimestamp*/,
- const client_cache_t& /*cachedBuffer*/,
- bool /*hasListenerCallbacks*/,
- const std::vector<ListenerCallbacks>& /*listenerCallbacks*/,
- uint64_t /*transactionId*/) override {
+ status_t setTransactionState(
+ const FrameTimelineInfo& /*frameTimelineInfo*/, Vector<ComposerState>& /*state*/,
+ const Vector<DisplayState>& /*displays*/, uint32_t /*flags*/,
+ const sp<IBinder>& /*applyToken*/, InputWindowCommands /*inputWindowCommands*/,
+ int64_t /*desiredPresentTime*/, bool /*isAutoTimestamp*/,
+ const std::vector<client_cache_t>& /*cachedBuffer*/, bool /*hasListenerCallbacks*/,
+ const std::vector<ListenerCallbacks>& /*listenerCallbacks*/, uint64_t /*transactionId*/,
+ const std::vector<uint64_t>& /*mergedTransactionIds*/) override {
return NO_ERROR;
}
- void bootFinished() override {}
- bool authenticateSurfaceTexture(
- const sp<IGraphicBufferProducer>& /*surface*/) const override {
- return false;
- }
+protected:
+ IBinder* onAsBinder() override { return nullptr; }
- status_t getSupportedFrameTimestamps(std::vector<FrameEvent>* outSupported)
- const override {
- *outSupported = {
- FrameEvent::REQUESTED_PRESENT,
- FrameEvent::ACQUIRE,
- FrameEvent::LATCH,
- FrameEvent::FIRST_REFRESH_START,
- FrameEvent::LAST_REFRESH_START,
- FrameEvent::GPU_COMPOSITION_DONE,
- FrameEvent::DEQUEUE_READY,
- FrameEvent::RELEASE
- };
- if (mSupportsPresent) {
- outSupported->push_back(
- FrameEvent::DISPLAY_PRESENT);
- }
- return NO_ERROR;
- }
+private:
+ bool mSupportsPresent{true};
+};
- status_t getStaticDisplayInfo(const sp<IBinder>& /*display*/, ui::StaticDisplayInfo*) override {
- return NO_ERROR;
- }
- status_t getDynamicDisplayInfo(const sp<IBinder>& /*display*/,
- ui::DynamicDisplayInfo*) override {
- return NO_ERROR;
- }
- status_t getDisplayNativePrimaries(const sp<IBinder>& /*display*/,
- ui::DisplayPrimaries& /*primaries*/) override {
- return NO_ERROR;
- }
- status_t setActiveColorMode(const sp<IBinder>& /*display*/, ColorMode /*colorMode*/) override {
- return NO_ERROR;
- }
- status_t setBootDisplayMode(const sp<IBinder>& /*display*/, ui::DisplayModeId /*id*/) override {
- return NO_ERROR;
- }
+class FakeSurfaceComposerAIDL : public gui::ISurfaceComposer {
+public:
+ ~FakeSurfaceComposerAIDL() override {}
- status_t clearAnimationFrameStats() override { return NO_ERROR; }
- status_t getAnimationFrameStats(FrameStats* /*outStats*/) const override {
- return NO_ERROR;
+ void setSupportsPresent(bool supportsPresent) { mSupportsPresent = supportsPresent; }
+
+ binder::Status bootFinished() override { return binder::Status::ok(); }
+
+ binder::Status createDisplayEventConnection(
+ VsyncSource /*vsyncSource*/, EventRegistration /*eventRegistration*/,
+ const sp<IBinder>& /*layerHandle*/,
+ sp<gui::IDisplayEventConnection>* outConnection) override {
+ *outConnection = nullptr;
+ return binder::Status::ok();
}
- status_t overrideHdrTypes(const sp<IBinder>& /*display*/,
- const std::vector<ui::Hdr>& /*hdrTypes*/) override {
- return NO_ERROR;
+
+ binder::Status createConnection(sp<gui::ISurfaceComposerClient>* outClient) override {
+ *outClient = nullptr;
+ return binder::Status::ok();
}
- status_t onPullAtom(const int32_t /*atomId*/, std::string* /*outData*/,
- bool* /*success*/) override {
- return NO_ERROR;
+
+ binder::Status createDisplay(const std::string& /*displayName*/, bool /*secure*/,
+ float /*requestedRefreshRate*/,
+ sp<IBinder>* /*outDisplay*/) override {
+ return binder::Status::ok();
}
- status_t enableVSyncInjections(bool /*enable*/) override {
- return NO_ERROR;
+
+ binder::Status destroyDisplay(const sp<IBinder>& /*display*/) override {
+ return binder::Status::ok();
}
- status_t injectVSync(nsecs_t /*when*/) override { return NO_ERROR; }
- status_t getLayerDebugInfo(std::vector<LayerDebugInfo>* /*layers*/) override {
- return NO_ERROR;
+
+ binder::Status getPhysicalDisplayIds(std::vector<int64_t>* /*outDisplayIds*/) override {
+ return binder::Status::ok();
}
- status_t getCompositionPreference(
- ui::Dataspace* /*outDefaultDataspace*/, ui::PixelFormat* /*outDefaultPixelFormat*/,
- ui::Dataspace* /*outWideColorGamutDataspace*/,
- ui::PixelFormat* /*outWideColorGamutPixelFormat*/) const override {
- return NO_ERROR;
+
+ binder::Status getPhysicalDisplayToken(int64_t /*displayId*/,
+ sp<IBinder>* /*outDisplay*/) override {
+ return binder::Status::ok();
}
- status_t getDisplayedContentSamplingAttributes(const sp<IBinder>& /*display*/,
- ui::PixelFormat* /*outFormat*/,
- ui::Dataspace* /*outDataspace*/,
- uint8_t* /*outComponentMask*/) const override {
- return NO_ERROR;
+
+ binder::Status setPowerMode(const sp<IBinder>& /*display*/, int /*mode*/) override {
+ return binder::Status::ok();
}
- status_t setDisplayContentSamplingEnabled(const sp<IBinder>& /*display*/, bool /*enable*/,
- uint8_t /*componentMask*/,
- uint64_t /*maxFrames*/) override {
- return NO_ERROR;
+
+ binder::Status getSupportedFrameTimestamps(std::vector<FrameEvent>* outSupported) override {
+ *outSupported = {FrameEvent::REQUESTED_PRESENT,
+ FrameEvent::ACQUIRE,
+ FrameEvent::LATCH,
+ FrameEvent::FIRST_REFRESH_START,
+ FrameEvent::LAST_REFRESH_START,
+ FrameEvent::GPU_COMPOSITION_DONE,
+ FrameEvent::DEQUEUE_READY,
+ FrameEvent::RELEASE};
+ if (mSupportsPresent) {
+ outSupported->push_back(FrameEvent::DISPLAY_PRESENT);
+ }
+ return binder::Status::ok();
}
- status_t getDisplayedContentSample(const sp<IBinder>& /*display*/, uint64_t /*maxFrames*/,
- uint64_t /*timestamp*/,
- DisplayedFrameStats* /*outStats*/) const override {
- return NO_ERROR;
+
+ binder::Status getDisplayStats(const sp<IBinder>& /*display*/,
+ gui::DisplayStatInfo* /*outStatInfo*/) override {
+ return binder::Status::ok();
}
- status_t getColorManagement(bool* /*outGetColorManagement*/) const override { return NO_ERROR; }
- status_t getProtectedContentSupport(bool* /*outSupported*/) const override { return NO_ERROR; }
+ binder::Status getDisplayState(const sp<IBinder>& /*display*/,
+ gui::DisplayState* /*outState*/) override {
+ return binder::Status::ok();
+ }
- status_t addRegionSamplingListener(const Rect& /*samplingArea*/,
- const sp<IBinder>& /*stopLayerHandle*/,
- const sp<IRegionSamplingListener>& /*listener*/) override {
- return NO_ERROR;
+ binder::Status getStaticDisplayInfo(int64_t /*displayId*/,
+ gui::StaticDisplayInfo* /*outInfo*/) override {
+ return binder::Status::ok();
}
- status_t removeRegionSamplingListener(
- const sp<IRegionSamplingListener>& /*listener*/) override {
- return NO_ERROR;
+
+ binder::Status getDynamicDisplayInfoFromId(int64_t /*displayId*/,
+ gui::DynamicDisplayInfo* /*outInfo*/) override {
+ return binder::Status::ok();
}
- status_t addFpsListener(int32_t /*taskId*/, const sp<gui::IFpsListener>& /*listener*/) {
- return NO_ERROR;
+
+ binder::Status getDynamicDisplayInfoFromToken(const sp<IBinder>& /*display*/,
+ gui::DynamicDisplayInfo* /*outInfo*/) override {
+ return binder::Status::ok();
}
- status_t removeFpsListener(const sp<gui::IFpsListener>& /*listener*/) { return NO_ERROR; }
- status_t addTunnelModeEnabledListener(const sp<gui::ITunnelModeEnabledListener>& /*listener*/) {
- return NO_ERROR;
+ binder::Status getDisplayNativePrimaries(const sp<IBinder>& /*display*/,
+ gui::DisplayPrimaries* /*outPrimaries*/) override {
+ return binder::Status::ok();
}
- status_t removeTunnelModeEnabledListener(
- const sp<gui::ITunnelModeEnabledListener>& /*listener*/) {
- return NO_ERROR;
+ binder::Status setActiveColorMode(const sp<IBinder>& /*display*/, int /*colorMode*/) override {
+ return binder::Status::ok();
}
- status_t setDesiredDisplayModeSpecs(const sp<IBinder>& /*displayToken*/,
- ui::DisplayModeId /*defaultMode*/,
- bool /*allowGroupSwitching*/,
- float /*primaryRefreshRateMin*/,
- float /*primaryRefreshRateMax*/,
- float /*appRequestRefreshRateMin*/,
- float /*appRequestRefreshRateMax*/) {
- return NO_ERROR;
+ binder::Status setBootDisplayMode(const sp<IBinder>& /*display*/,
+ int /*displayModeId*/) override {
+ return binder::Status::ok();
}
- status_t getDesiredDisplayModeSpecs(const sp<IBinder>& /*displayToken*/,
- ui::DisplayModeId* /*outDefaultMode*/,
- bool* /*outAllowGroupSwitching*/,
- float* /*outPrimaryRefreshRateMin*/,
- float* /*outPrimaryRefreshRateMax*/,
- float* /*outAppRequestRefreshRateMin*/,
- float* /*outAppRequestRefreshRateMax*/) override {
- return NO_ERROR;
- };
- status_t setGlobalShadowSettings(const half4& /*ambientColor*/, const half4& /*spotColor*/,
- float /*lightPosY*/, float /*lightPosZ*/,
- float /*lightRadius*/) override {
- return NO_ERROR;
+ binder::Status clearBootDisplayMode(const sp<IBinder>& /*display*/) override {
+ return binder::Status::ok();
}
- status_t getDisplayDecorationSupport(
- const sp<IBinder>& /*displayToken*/,
- std::optional<DisplayDecorationSupport>* /*outSupport*/) const override {
- return NO_ERROR;
+ binder::Status getBootDisplayModeSupport(bool* /*outMode*/) override {
+ return binder::Status::ok();
}
- status_t setFrameRate(const sp<IGraphicBufferProducer>& /*surface*/, float /*frameRate*/,
- int8_t /*compatibility*/, int8_t /*changeFrameRateStrategy*/) override {
- return NO_ERROR;
+ binder::Status getHdrConversionCapabilities(
+ std::vector<gui::HdrConversionCapability>*) override {
+ return binder::Status::ok();
}
- status_t setFrameTimelineInfo(const sp<IGraphicBufferProducer>& /*surface*/,
- const FrameTimelineInfo& /*frameTimelineInfo*/) override {
- return NO_ERROR;
+ binder::Status setHdrConversionStrategy(
+ const gui::HdrConversionStrategy& /*hdrConversionStrategy*/,
+ int32_t* /*outPreferredHdrOutputType*/) override {
+ return binder::Status::ok();
}
- status_t addTransactionTraceListener(
- const sp<gui::ITransactionTraceListener>& /*listener*/) override {
- return NO_ERROR;
+ binder::Status getHdrOutputConversionSupport(bool* /*outSupport*/) override {
+ return binder::Status::ok();
}
- int getGPUContextPriority() override { return 0; };
+ binder::Status setAutoLowLatencyMode(const sp<IBinder>& /*display*/, bool /*on*/) override {
+ return binder::Status::ok();
+ }
- status_t getMaxAcquiredBufferCount(int* /*buffers*/) const override { return NO_ERROR; }
+ binder::Status setGameContentType(const sp<IBinder>& /*display*/, bool /*on*/) override {
+ return binder::Status::ok();
+ }
- status_t addWindowInfosListener(
- const sp<gui::IWindowInfosListener>& /*windowInfosListener*/) const override {
- return NO_ERROR;
+ binder::Status captureDisplay(const DisplayCaptureArgs&,
+ const sp<IScreenCaptureListener>&) override {
+ return binder::Status::ok();
}
- status_t removeWindowInfosListener(
- const sp<gui::IWindowInfosListener>& /*windowInfosListener*/) const override {
- return NO_ERROR;
+ binder::Status captureDisplayById(int64_t, const sp<IScreenCaptureListener>&) override {
+ return binder::Status::ok();
}
- status_t setOverrideFrameRate(uid_t /*uid*/, float /*frameRate*/) override { return NO_ERROR; }
+ binder::Status captureLayers(const LayerCaptureArgs&,
+ const sp<IScreenCaptureListener>&) override {
+ return binder::Status::ok();
+ }
-protected:
- IBinder* onAsBinder() override { return nullptr; }
+ binder::Status clearAnimationFrameStats() override { return binder::Status::ok(); }
-private:
- bool mSupportsPresent{true};
-};
+ binder::Status getAnimationFrameStats(gui::FrameStats* /*outStats*/) override {
+ return binder::Status::ok();
+ }
-class FakeSurfaceComposerAIDL : public gui::ISurfaceComposer {
-public:
- ~FakeSurfaceComposerAIDL() override {}
+ binder::Status overrideHdrTypes(const sp<IBinder>& /*display*/,
+ const std::vector<int32_t>& /*hdrTypes*/) override {
+ return binder::Status::ok();
+ }
- void setSupportsPresent(bool supportsPresent) { mSupportsPresent = supportsPresent; }
+ binder::Status onPullAtom(int32_t /*atomId*/, gui::PullAtomData* /*outPullData*/) override {
+ return binder::Status::ok();
+ }
- binder::Status createDisplay(const std::string& /*displayName*/, bool /*secure*/,
- sp<IBinder>* /*outDisplay*/) override {
+ binder::Status getLayerDebugInfo(std::vector<gui::LayerDebugInfo>* /*outLayers*/) override {
return binder::Status::ok();
}
- binder::Status destroyDisplay(const sp<IBinder>& /*display*/) override {
+ binder::Status getColorManagement(bool* /*outGetColorManagement*/) override {
return binder::Status::ok();
}
- binder::Status getPhysicalDisplayIds(std::vector<int64_t>* /*outDisplayIds*/) override {
+ binder::Status getCompositionPreference(gui::CompositionPreference* /*outPref*/) override {
return binder::Status::ok();
}
- binder::Status getPrimaryPhysicalDisplayId(int64_t* /*outDisplayId*/) override {
+ binder::Status getDisplayedContentSamplingAttributes(
+ const sp<IBinder>& /*display*/, gui::ContentSamplingAttributes* /*outAttrs*/) override {
return binder::Status::ok();
}
- binder::Status getPhysicalDisplayToken(int64_t /*displayId*/,
- sp<IBinder>* /*outDisplay*/) override {
+ binder::Status setDisplayContentSamplingEnabled(const sp<IBinder>& /*display*/, bool /*enable*/,
+ int8_t /*componentMask*/,
+ int64_t /*maxFrames*/) override {
return binder::Status::ok();
}
- binder::Status setPowerMode(const sp<IBinder>& /*display*/, int /*mode*/) override {
+ binder::Status getProtectedContentSupport(bool* /*outSupporte*/) override {
return binder::Status::ok();
}
- binder::Status getDisplayStats(const sp<IBinder>& /*display*/,
- gui::DisplayStatInfo* /*outStatInfo*/) override {
+ binder::Status getDisplayedContentSample(const sp<IBinder>& /*display*/, int64_t /*maxFrames*/,
+ int64_t /*timestamp*/,
+ gui::DisplayedFrameStats* /*outStats*/) override {
return binder::Status::ok();
}
- binder::Status getDisplayState(const sp<IBinder>& /*display*/,
- gui::DisplayState* /*outState*/) override {
+ binder::Status isWideColorDisplay(const sp<IBinder>& /*token*/,
+ bool* /*outIsWideColorDisplay*/) override {
return binder::Status::ok();
}
- binder::Status clearBootDisplayMode(const sp<IBinder>& /*display*/) override {
+ binder::Status addRegionSamplingListener(
+ const gui::ARect& /*samplingArea*/, const sp<IBinder>& /*stopLayerHandle*/,
+ const sp<gui::IRegionSamplingListener>& /*listener*/) override {
return binder::Status::ok();
}
- binder::Status getBootDisplayModeSupport(bool* /*outMode*/) override {
+ binder::Status removeRegionSamplingListener(
+ const sp<gui::IRegionSamplingListener>& /*listener*/) override {
return binder::Status::ok();
}
- binder::Status setAutoLowLatencyMode(const sp<IBinder>& /*display*/, bool /*on*/) override {
+ binder::Status addFpsListener(int32_t /*taskId*/,
+ const sp<gui::IFpsListener>& /*listener*/) override {
return binder::Status::ok();
}
- binder::Status setGameContentType(const sp<IBinder>& /*display*/, bool /*on*/) override {
+ binder::Status removeFpsListener(const sp<gui::IFpsListener>& /*listener*/) override {
return binder::Status::ok();
}
- binder::Status captureDisplay(const DisplayCaptureArgs&,
- const sp<IScreenCaptureListener>&) override {
+ binder::Status addTunnelModeEnabledListener(
+ const sp<gui::ITunnelModeEnabledListener>& /*listener*/) override {
return binder::Status::ok();
}
- binder::Status captureDisplayById(int64_t, const sp<IScreenCaptureListener>&) override {
+ binder::Status removeTunnelModeEnabledListener(
+ const sp<gui::ITunnelModeEnabledListener>& /*listener*/) override {
return binder::Status::ok();
}
- binder::Status captureLayers(const LayerCaptureArgs&,
- const sp<IScreenCaptureListener>&) override {
+ binder::Status setDesiredDisplayModeSpecs(const sp<IBinder>& /*displayToken*/,
+ const gui::DisplayModeSpecs&) override {
return binder::Status::ok();
}
- binder::Status isWideColorDisplay(const sp<IBinder>& /*token*/,
- bool* /*outIsWideColorDisplay*/) override {
+ binder::Status getDesiredDisplayModeSpecs(const sp<IBinder>& /*displayToken*/,
+ gui::DisplayModeSpecs*) override {
return binder::Status::ok();
}
@@ -989,6 +973,45 @@ public:
binder::Status notifyPowerBoost(int /*boostId*/) override { return binder::Status::ok(); }
+ binder::Status setGlobalShadowSettings(const gui::Color& /*ambientColor*/,
+ const gui::Color& /*spotColor*/, float /*lightPosY*/,
+ float /*lightPosZ*/, float /*lightRadius*/) override {
+ return binder::Status::ok();
+ }
+
+ binder::Status getDisplayDecorationSupport(
+ const sp<IBinder>& /*displayToken*/,
+ std::optional<gui::DisplayDecorationSupport>* /*outSupport*/) override {
+ return binder::Status::ok();
+ }
+
+ binder::Status setOverrideFrameRate(int32_t /*uid*/, float /*frameRate*/) override {
+ return binder::Status::ok();
+ }
+
+ binder::Status getGpuContextPriority(int32_t* /*outPriority*/) override {
+ return binder::Status::ok();
+ }
+
+ binder::Status getMaxAcquiredBufferCount(int32_t* /*buffers*/) override {
+ return binder::Status::ok();
+ }
+
+ binder::Status addWindowInfosListener(
+ const sp<gui::IWindowInfosListener>& /*windowInfosListener*/,
+ gui::WindowInfosListenerInfo* /*outInfo*/) override {
+ return binder::Status::ok();
+ }
+
+ binder::Status removeWindowInfosListener(
+ const sp<gui::IWindowInfosListener>& /*windowInfosListener*/) override {
+ return binder::Status::ok();
+ }
+
+ binder::Status getOverlaySupport(gui::OverlayProperties* /*properties*/) override {
+ return binder::Status::ok();
+ }
+
protected:
IBinder* onAsBinder() override { return nullptr; }
@@ -1034,10 +1057,10 @@ protected:
class TestSurface : public Surface {
public:
- TestSurface(const sp<IGraphicBufferProducer>& bufferProducer,
- FenceToFenceTimeMap* fenceMap)
- : Surface(bufferProducer),
- mFakeSurfaceComposer(new FakeSurfaceComposer) {
+ TestSurface(const sp<IGraphicBufferProducer>& bufferProducer, FenceToFenceTimeMap* fenceMap)
+ : Surface(bufferProducer),
+ mFakeSurfaceComposer(new FakeSurfaceComposer),
+ mFakeSurfaceComposerAIDL(new FakeSurfaceComposerAIDL) {
mFakeFrameEventHistory = new FakeProducerFrameEventHistory(fenceMap);
mFrameEventHistory.reset(mFakeFrameEventHistory);
}
@@ -1048,6 +1071,10 @@ public:
return mFakeSurfaceComposer;
}
+ sp<gui::ISurfaceComposer> composerServiceAIDL() const override {
+ return mFakeSurfaceComposerAIDL;
+ }
+
nsecs_t now() const override {
return mNow;
}
@@ -1058,6 +1085,7 @@ public:
public:
sp<FakeSurfaceComposer> mFakeSurfaceComposer;
+ sp<FakeSurfaceComposerAIDL> mFakeSurfaceComposerAIDL;
nsecs_t mNow = 0;
// mFrameEventHistory owns the instance of FakeProducerFrameEventHistory,
@@ -1070,20 +1098,30 @@ class GetFrameTimestampsTest : public ::testing::Test {
protected:
struct FenceAndFenceTime {
explicit FenceAndFenceTime(FenceToFenceTimeMap& fenceMap)
- : mFence(new Fence),
- mFenceTime(fenceMap.createFenceTimeForTest(mFence)) {}
- sp<Fence> mFence { nullptr };
- std::shared_ptr<FenceTime> mFenceTime { nullptr };
+ : mFenceTime(fenceMap.createFenceTimeForTest(mFence)) {}
+
+ sp<Fence> mFence = sp<Fence>::make();
+ std::shared_ptr<FenceTime> mFenceTime;
};
+ static CompositorTiming makeCompositorTiming(nsecs_t deadline = 1'000'000'000,
+ nsecs_t interval = 16'666'667,
+ nsecs_t presentLatency = 50'000'000) {
+ CompositorTiming timing;
+ timing.deadline = deadline;
+ timing.interval = interval;
+ timing.presentLatency = presentLatency;
+ return timing;
+ }
+
struct RefreshEvents {
RefreshEvents(FenceToFenceTimeMap& fenceMap, nsecs_t refreshStart)
- : mFenceMap(fenceMap),
- kCompositorTiming(
- {refreshStart, refreshStart + 1, refreshStart + 2 }),
- kStartTime(refreshStart + 3),
- kGpuCompositionDoneTime(refreshStart + 4),
- kPresentTime(refreshStart + 5) {}
+ : mFenceMap(fenceMap),
+ kCompositorTiming(
+ makeCompositorTiming(refreshStart, refreshStart + 1, refreshStart + 2)),
+ kStartTime(refreshStart + 3),
+ kGpuCompositionDoneTime(refreshStart + 4),
+ kPresentTime(refreshStart + 5) {}
void signalPostCompositeFences() {
mFenceMap.signalAllForTest(
@@ -1093,8 +1131,8 @@ protected:
FenceToFenceTimeMap& mFenceMap;
- FenceAndFenceTime mGpuCompositionDone { mFenceMap };
- FenceAndFenceTime mPresent { mFenceMap };
+ FenceAndFenceTime mGpuCompositionDone{mFenceMap};
+ FenceAndFenceTime mPresent{mFenceMap};
const CompositorTiming kCompositorTiming;
@@ -1360,11 +1398,7 @@ TEST_F(GetFrameTimestampsTest, DefaultDisabled) {
// This test verifies that the frame timestamps are retrieved if explicitly
// enabled via native_window_enable_frame_timestamps.
TEST_F(GetFrameTimestampsTest, EnabledSimple) {
- CompositorTiming initialCompositorTiming {
- 1000000000, // 1s deadline
- 16666667, // 16ms interval
- 50000000, // 50ms present latency
- };
+ const CompositorTiming initialCompositorTiming = makeCompositorTiming();
mCfeh->initializeCompositorTiming(initialCompositorTiming);
enableFrameTimestamps();
@@ -1424,6 +1458,7 @@ TEST_F(GetFrameTimestampsTest, EnabledSimple) {
TEST_F(GetFrameTimestampsTest, QueryPresentSupported) {
bool displayPresentSupported = true;
mSurface->mFakeSurfaceComposer->setSupportsPresent(displayPresentSupported);
+ mSurface->mFakeSurfaceComposerAIDL->setSupportsPresent(displayPresentSupported);
// Verify supported bits are forwarded.
int supportsPresent = -1;
@@ -1435,6 +1470,7 @@ TEST_F(GetFrameTimestampsTest, QueryPresentSupported) {
TEST_F(GetFrameTimestampsTest, QueryPresentNotSupported) {
bool displayPresentSupported = false;
mSurface->mFakeSurfaceComposer->setSupportsPresent(displayPresentSupported);
+ mSurface->mFakeSurfaceComposerAIDL->setSupportsPresent(displayPresentSupported);
// Verify supported bits are forwarded.
int supportsPresent = -1;
@@ -1501,11 +1537,7 @@ TEST_F(GetFrameTimestampsTest, SnapToNextTickOverflow) {
// This verifies the compositor timing is updated by refresh events
// and piggy backed on a queue, dequeue, and enabling of timestamps..
TEST_F(GetFrameTimestampsTest, CompositorTimingUpdatesBasic) {
- CompositorTiming initialCompositorTiming {
- 1000000000, // 1s deadline
- 16666667, // 16ms interval
- 50000000, // 50ms present latency
- };
+ const CompositorTiming initialCompositorTiming = makeCompositorTiming();
mCfeh->initializeCompositorTiming(initialCompositorTiming);
enableFrameTimestamps();
@@ -1586,11 +1618,7 @@ TEST_F(GetFrameTimestampsTest, CompositorTimingUpdatesBasic) {
// This verifies the compositor deadline properly snaps to the the next
// deadline based on the current time.
TEST_F(GetFrameTimestampsTest, CompositorTimingDeadlineSnaps) {
- CompositorTiming initialCompositorTiming {
- 1000000000, // 1s deadline
- 16666667, // 16ms interval
- 50000000, // 50ms present latency
- };
+ const CompositorTiming initialCompositorTiming = makeCompositorTiming();
mCfeh->initializeCompositorTiming(initialCompositorTiming);
enableFrameTimestamps();
@@ -2012,6 +2040,7 @@ TEST_F(GetFrameTimestampsTest, NoReleaseNoSync) {
TEST_F(GetFrameTimestampsTest, PresentUnsupportedNoSync) {
enableFrameTimestamps();
mSurface->mFakeSurfaceComposer->setSupportsPresent(false);
+ mSurface->mFakeSurfaceComposerAIDL->setSupportsPresent(false);
// Dequeue and queue frame 1.
const uint64_t fId1 = getNextFrameId();
diff --git a/libs/gui/tests/VsyncEventData_test.cpp b/libs/gui/tests/VsyncEventData_test.cpp
index f114522951..a2138f2144 100644
--- a/libs/gui/tests/VsyncEventData_test.cpp
+++ b/libs/gui/tests/VsyncEventData_test.cpp
@@ -36,6 +36,7 @@ TEST(ParcelableVsyncEventData, Parcelling) {
FrameTimeline timeline1 = FrameTimeline{4, 5, 6};
data.vsync.frameTimelines[0] = timeline0;
data.vsync.frameTimelines[1] = timeline1;
+ data.vsync.frameTimelinesLength = 2;
Parcel p;
data.writeToParcel(&p);
@@ -45,7 +46,8 @@ TEST(ParcelableVsyncEventData, Parcelling) {
data2.readFromParcel(&p);
ASSERT_EQ(data.vsync.frameInterval, data2.vsync.frameInterval);
ASSERT_EQ(data.vsync.preferredFrameTimelineIndex, data2.vsync.preferredFrameTimelineIndex);
- for (int i = 0; i < VsyncEventData::kFrameTimelinesLength; i++) {
+ ASSERT_EQ(data.vsync.frameTimelinesLength, data2.vsync.frameTimelinesLength);
+ for (int i = 0; i < VsyncEventData::kFrameTimelinesCapacity; i++) {
ASSERT_EQ(data.vsync.frameTimelines[i].vsyncId, data2.vsync.frameTimelines[i].vsyncId);
ASSERT_EQ(data.vsync.frameTimelines[i].deadlineTimestamp,
data2.vsync.frameTimelines[i].deadlineTimestamp);
diff --git a/libs/gui/tests/WindowInfo_test.cpp b/libs/gui/tests/WindowInfo_test.cpp
index 99658ccd4b..11b87efda7 100644
--- a/libs/gui/tests/WindowInfo_test.cpp
+++ b/libs/gui/tests/WindowInfo_test.cpp
@@ -71,7 +71,7 @@ TEST(WindowInfo, Parcelling) {
i.applicationInfo.name = "ApplicationFooBar";
i.applicationInfo.token = new BBinder();
i.applicationInfo.dispatchingTimeoutMillis = 0x12345678ABCD;
- i.isClone = true;
+ i.focusTransferTarget = new BBinder();
Parcel p;
i.writeToParcel(&p);
@@ -102,7 +102,7 @@ TEST(WindowInfo, Parcelling) {
ASSERT_EQ(i.replaceTouchableRegionWithCrop, i2.replaceTouchableRegionWithCrop);
ASSERT_EQ(i.touchableRegionCropHandle, i2.touchableRegionCropHandle);
ASSERT_EQ(i.applicationInfo, i2.applicationInfo);
- ASSERT_EQ(i.isClone, i2.isClone);
+ ASSERT_EQ(i.focusTransferTarget, i2.focusTransferTarget);
}
TEST(InputApplicationInfo, Parcelling) {