Merge "Remove legacy layer gamemode" into main
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index 6576ffd..220fef6 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -1559,6 +1559,13 @@
CommandOptions::WithTimeout(90).Build(), SEC_TO_MSEC(10));
printf("========================================================\n");
+ printf("== Networking Policy\n");
+ printf("========================================================\n");
+
+ RunDumpsys("DUMPSYS NETWORK POLICY", {"netpolicy"}, CommandOptions::WithTimeout(90).Build(),
+ SEC_TO_MSEC(10));
+
+ printf("========================================================\n");
printf("== Dropbox crashes\n");
printf("========================================================\n");
diff --git a/cmds/installd/otapreopt_script.sh b/cmds/installd/otapreopt_script.sh
index 9384926..28bd793 100644
--- a/cmds/installd/otapreopt_script.sh
+++ b/cmds/installd/otapreopt_script.sh
@@ -50,37 +50,6 @@
exit 1
fi
-# A source that infinitely emits arbitrary lines.
-# When connected to STDIN of another process, this source keeps STDIN open until
-# the consumer process closes STDIN or this script dies.
-function infinite_source {
- while echo .; do
- sleep 1
- done
-}
-
-PR_DEXOPT_JOB_VERSION="$(pm art pr-dexopt-job --version)"
-if (( $? == 0 )) && (( $PR_DEXOPT_JOB_VERSION >= 2 )); then
- # Delegate to Pre-reboot Dexopt, a feature of ART Service.
- # ART Service decides what to do with this request:
- # - If Pre-reboot Dexopt is disabled or unsupported, the command returns
- # non-zero. This is always the case if the current system is Android 14 or
- # earlier.
- # - If Pre-reboot Dexopt is enabled in synchronous mode, the command blocks
- # until Pre-reboot Dexopt finishes, and returns zero no matter it succeeds or
- # not. This is the default behavior if the current system is Android 15.
- # - If Pre-reboot Dexopt is enabled in asynchronous mode, the command schedules
- # an asynchronous job and returns 0 immediately. The job will then run by the
- # job scheduler when the device is idle and charging.
- if infinite_source | pm art on-ota-staged --slot "$TARGET_SLOT_SUFFIX"; then
- # Handled by Pre-reboot Dexopt.
- exit 0
- fi
- echo "Pre-reboot Dexopt not enabled. Fall back to otapreopt."
-else
- echo "Pre-reboot Dexopt is too old. Fall back to otapreopt."
-fi
-
if [ "$(/system/bin/otapreopt_chroot --version)" != 2 ]; then
# We require an updated chroot wrapper that reads dexopt commands from stdin.
# Even if we kept compat with the old binary, the OTA preopt wouldn't work due
diff --git a/libs/bufferstreams/examples/app/java/com/android/graphics/bufferstreamsdemoapp/BufferDemosAppBar.kt b/libs/bufferstreams/examples/app/java/com/android/graphics/bufferstreamsdemoapp/BufferDemosAppBar.kt
index ff3ae5a..4f293b9 100644
--- a/libs/bufferstreams/examples/app/java/com/android/graphics/bufferstreamsdemoapp/BufferDemosAppBar.kt
+++ b/libs/bufferstreams/examples/app/java/com/android/graphics/bufferstreamsdemoapp/BufferDemosAppBar.kt
@@ -1,7 +1,5 @@
package com.android.graphics.bufferstreamsdemoapp
-import androidx.compose.material.icons.Icons
-import androidx.compose.material.icons.automirrored.filled.ArrowBack
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
@@ -29,10 +27,11 @@
navigationIcon = {
if (canNavigateBack) {
IconButton(onClick = navigateUp) {
- Icon(
- imageVector = Icons.AutoMirrored.Filled.ArrowBack,
- contentDescription = stringResource(R.string.back_button)
- )
+ // b/355293776
+ // Icon(
+ // imageVector = Icons.AutoMirrored.Filled.ArrowBack,
+ // contentDescription = stringResource(R.string.back_button)
+ // )
}
}
}
diff --git a/libs/gui/BufferItemConsumer.cpp b/libs/gui/BufferItemConsumer.cpp
index e6331e7..eeb8f19 100644
--- a/libs/gui/BufferItemConsumer.cpp
+++ b/libs/gui/BufferItemConsumer.cpp
@@ -21,8 +21,11 @@
#include <inttypes.h>
+#include <com_android_graphics_libgui_flags.h>
#include <gui/BufferItem.h>
#include <gui/BufferItemConsumer.h>
+#include <ui/BufferQueueDefs.h>
+#include <ui/GraphicBuffer.h>
#define BI_LOGV(x, ...) ALOGV("[%s] " x, mName.c_str(), ##__VA_ARGS__)
// #define BI_LOGD(x, ...) ALOGD("[%s] " x, mName.c_str(), ##__VA_ARGS__)
@@ -87,17 +90,38 @@
status_t BufferItemConsumer::releaseBuffer(const BufferItem &item,
const sp<Fence>& releaseFence) {
- status_t err;
+ Mutex::Autolock _l(mMutex);
+ return releaseBufferSlotLocked(item.mSlot, item.mGraphicBuffer, releaseFence);
+}
+#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)
+status_t BufferItemConsumer::releaseBuffer(const sp<GraphicBuffer>& buffer,
+ const sp<Fence>& releaseFence) {
Mutex::Autolock _l(mMutex);
- err = addReleaseFenceLocked(item.mSlot, item.mGraphicBuffer, releaseFence);
+ if (buffer == nullptr) {
+ return BAD_VALUE;
+ }
+
+ int slotIndex = getSlotForBufferLocked(buffer);
+ if (slotIndex == INVALID_BUFFER_SLOT) {
+ return BAD_VALUE;
+ }
+
+ return releaseBufferSlotLocked(slotIndex, buffer, releaseFence);
+}
+#endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)
+
+status_t BufferItemConsumer::releaseBufferSlotLocked(int slotIndex, const sp<GraphicBuffer>& buffer,
+ const sp<Fence>& releaseFence) {
+ status_t err;
+
+ err = addReleaseFenceLocked(slotIndex, buffer, releaseFence);
if (err != OK) {
BI_LOGE("Failed to addReleaseFenceLocked");
}
- err = releaseBufferLocked(item.mSlot, item.mGraphicBuffer, EGL_NO_DISPLAY,
- EGL_NO_SYNC_KHR);
+ err = releaseBufferLocked(slotIndex, buffer, EGL_NO_DISPLAY, EGL_NO_SYNC_KHR);
if (err != OK && err != IGraphicBufferConsumer::STALE_BUFFER_SLOT) {
BI_LOGE("Failed to release buffer: %s (%d)",
strerror(-err), err);
diff --git a/libs/gui/ConsumerBase.cpp b/libs/gui/ConsumerBase.cpp
index b625c3f..19b9c8b 100644
--- a/libs/gui/ConsumerBase.cpp
+++ b/libs/gui/ConsumerBase.cpp
@@ -30,9 +30,10 @@
#include <cutils/atomic.h>
#include <gui/BufferItem.h>
+#include <gui/ConsumerBase.h>
#include <gui/ISurfaceComposer.h>
#include <gui/SurfaceComposerClient.h>
-#include <gui/ConsumerBase.h>
+#include <ui/BufferQueueDefs.h>
#include <private/gui/ComposerService.h>
@@ -40,6 +41,8 @@
#include <utils/String8.h>
#include <utils/Trace.h>
+#include <com_android_graphics_libgui_flags.h>
+
// Macros for including the ConsumerBase name in log messages
#define CB_LOGV(x, ...) ALOGV("[%s] " x, mName.c_str(), ##__VA_ARGS__)
// #define CB_LOGD(x, ...) ALOGD("[%s] " x, mName.c_str(), ##__VA_ARGS__)
@@ -96,6 +99,35 @@
abandon();
}
+int ConsumerBase::getSlotForBufferLocked(const sp<GraphicBuffer>& buffer) {
+ if (!buffer) {
+ return BufferQueue::INVALID_BUFFER_SLOT;
+ }
+
+ uint64_t id = buffer->getId();
+ for (int i = 0; i < BufferQueueDefs::NUM_BUFFER_SLOTS; i++) {
+ auto& slot = mSlots[i];
+ if (slot.mGraphicBuffer && slot.mGraphicBuffer->getId() == id) {
+ return i;
+ }
+ }
+
+ return BufferQueue::INVALID_BUFFER_SLOT;
+}
+
+status_t ConsumerBase::detachBufferLocked(int slotIndex) {
+ status_t result = mConsumer->detachBuffer(slotIndex);
+
+ if (result != NO_ERROR) {
+ CB_LOGE("Failed to detach buffer: %d", result);
+ return result;
+ }
+
+ freeBufferLocked(slotIndex);
+
+ return result;
+}
+
void ConsumerBase::freeBufferLocked(int slotIndex) {
CB_LOGV("freeBufferLocked: slotIndex=%d", slotIndex);
mSlots[slotIndex].mGraphicBuffer = nullptr;
@@ -252,16 +284,30 @@
return NO_INIT;
}
- status_t result = mConsumer->detachBuffer(slot);
- if (result != NO_ERROR) {
- CB_LOGE("Failed to detach buffer: %d", result);
- return result;
+ return detachBufferLocked(slot);
+}
+
+#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)
+status_t ConsumerBase::detachBuffer(const sp<GraphicBuffer>& buffer) {
+ CB_LOGV("detachBuffer");
+ Mutex::Autolock lock(mMutex);
+
+ if (mAbandoned) {
+ CB_LOGE("detachBuffer: ConsumerBase is abandoned!");
+ return NO_INIT;
+ }
+ if (buffer == nullptr) {
+ return BAD_VALUE;
}
- freeBufferLocked(slot);
+ int slotIndex = getSlotForBufferLocked(buffer);
+ if (slotIndex == BufferQueue::INVALID_BUFFER_SLOT) {
+ return BAD_VALUE;
+ }
- return result;
+ return detachBufferLocked(slotIndex);
}
+#endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)
status_t ConsumerBase::setDefaultBufferSize(uint32_t width, uint32_t height) {
Mutex::Autolock _l(mMutex);
diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp
index eb9faf5..a98a3c0 100644
--- a/libs/gui/Surface.cpp
+++ b/libs/gui/Surface.cpp
@@ -1168,6 +1168,117 @@
}
}
+#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)
+
+int Surface::queueBuffer(android_native_buffer_t* buffer, int fenceFd) {
+ ATRACE_CALL();
+ ALOGV("Surface::queueBuffer");
+
+ IGraphicBufferProducer::QueueBufferOutput output;
+ IGraphicBufferProducer::QueueBufferInput input;
+ int slot;
+ sp<Fence> fence;
+ {
+ Mutex::Autolock lock(mMutex);
+
+ slot = getSlotFromBufferLocked(buffer);
+ if (slot < 0) {
+ if (fenceFd >= 0) {
+ close(fenceFd);
+ }
+ return slot;
+ }
+ if (mSharedBufferSlot == slot && mSharedBufferHasBeenQueued) {
+ if (fenceFd >= 0) {
+ close(fenceFd);
+ }
+ return OK;
+ }
+
+ getQueueBufferInputLocked(buffer, fenceFd, mTimestamp, &input);
+ applyGrallocMetadataLocked(buffer, input);
+ fence = input.fence;
+ }
+ nsecs_t now = systemTime();
+ // Drop the lock temporarily while we touch the underlying producer. In the case of a local
+ // BufferQueue, the following should be allowable:
+ //
+ // Surface::queueBuffer
+ // -> IConsumerListener::onFrameAvailable callback triggers automatically
+ // -> implementation calls IGraphicBufferConsumer::acquire/release immediately
+ // -> SurfaceListener::onBufferRelesed callback triggers automatically
+ // -> implementation calls Surface::dequeueBuffer
+ status_t err = mGraphicBufferProducer->queueBuffer(slot, input, &output);
+ {
+ Mutex::Autolock lock(mMutex);
+
+ mLastQueueDuration = systemTime() - now;
+ if (err != OK) {
+ ALOGE("queueBuffer: error queuing buffer, %d", err);
+ }
+
+ onBufferQueuedLocked(slot, fence, output);
+ }
+
+ return err;
+}
+
+int Surface::queueBuffers(const std::vector<BatchQueuedBuffer>& buffers) {
+ ATRACE_CALL();
+ ALOGV("Surface::queueBuffers");
+
+ size_t numBuffers = buffers.size();
+ std::vector<IGraphicBufferProducer::QueueBufferInput> queueBufferInputs(numBuffers);
+ std::vector<IGraphicBufferProducer::QueueBufferOutput> queueBufferOutputs;
+ std::vector<int> bufferSlots(numBuffers, -1);
+ std::vector<sp<Fence>> bufferFences(numBuffers);
+
+ int err;
+ {
+ Mutex::Autolock lock(mMutex);
+
+ if (mSharedBufferMode) {
+ ALOGE("%s: batched operation is not supported in shared buffer mode", __FUNCTION__);
+ return INVALID_OPERATION;
+ }
+
+ for (size_t batchIdx = 0; batchIdx < numBuffers; batchIdx++) {
+ int i = getSlotFromBufferLocked(buffers[batchIdx].buffer);
+ if (i < 0) {
+ if (buffers[batchIdx].fenceFd >= 0) {
+ close(buffers[batchIdx].fenceFd);
+ }
+ return i;
+ }
+ bufferSlots[batchIdx] = i;
+
+ IGraphicBufferProducer::QueueBufferInput input;
+ getQueueBufferInputLocked(buffers[batchIdx].buffer, buffers[batchIdx].fenceFd,
+ buffers[batchIdx].timestamp, &input);
+ bufferFences[batchIdx] = input.fence;
+ queueBufferInputs[batchIdx] = input;
+ }
+ }
+ nsecs_t now = systemTime();
+ err = mGraphicBufferProducer->queueBuffers(queueBufferInputs, &queueBufferOutputs);
+ {
+ Mutex::Autolock lock(mMutex);
+ mLastQueueDuration = systemTime() - now;
+ if (err != OK) {
+ ALOGE("%s: error queuing buffer, %d", __FUNCTION__, err);
+ }
+
+ for (size_t batchIdx = 0; batchIdx < numBuffers; batchIdx++) {
+ onBufferQueuedLocked(bufferSlots[batchIdx], bufferFences[batchIdx],
+ queueBufferOutputs[batchIdx]);
+ }
+ }
+
+ return err;
+}
+
+#else
+
int Surface::queueBuffer(android_native_buffer_t* buffer, int fenceFd) {
ATRACE_CALL();
ALOGV("Surface::queueBuffer");
@@ -1255,6 +1366,8 @@
return err;
}
+#endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)
+
void Surface::querySupportedTimestampsLocked() const {
// mMutex must be locked when calling this method.
diff --git a/libs/gui/include/gui/BufferItemConsumer.h b/libs/gui/include/gui/BufferItemConsumer.h
index a905610..e383a40 100644
--- a/libs/gui/include/gui/BufferItemConsumer.h
+++ b/libs/gui/include/gui/BufferItemConsumer.h
@@ -17,13 +17,15 @@
#ifndef ANDROID_GUI_BUFFERITEMCONSUMER_H
#define ANDROID_GUI_BUFFERITEMCONSUMER_H
-#include <gui/ConsumerBase.h>
+#include <com_android_graphics_libgui_flags.h>
#include <gui/BufferQueue.h>
+#include <gui/ConsumerBase.h>
#define ANDROID_GRAPHICS_BUFFERITEMCONSUMER_JNI_ID "mBufferItemConsumer"
namespace android {
+class GraphicBuffer;
class String8;
/**
@@ -85,7 +87,15 @@
status_t releaseBuffer(const BufferItem &item,
const sp<Fence>& releaseFence = Fence::NO_FENCE);
- private:
+#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)
+ status_t releaseBuffer(const sp<GraphicBuffer>& buffer,
+ const sp<Fence>& releaseFence = Fence::NO_FENCE);
+#endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)
+
+private:
+ status_t releaseBufferSlotLocked(int slotIndex, const sp<GraphicBuffer>& buffer,
+ const sp<Fence>& releaseFence);
+
void freeBufferLocked(int slotIndex) override;
// mBufferFreedListener is the listener object that will be called when
diff --git a/libs/gui/include/gui/ConsumerBase.h b/libs/gui/include/gui/ConsumerBase.h
index 8ff0cd0..a031e66 100644
--- a/libs/gui/include/gui/ConsumerBase.h
+++ b/libs/gui/include/gui/ConsumerBase.h
@@ -17,18 +17,16 @@
#ifndef ANDROID_GUI_CONSUMERBASE_H
#define ANDROID_GUI_CONSUMERBASE_H
+#include <com_android_graphics_libgui_flags.h>
#include <gui/BufferQueueDefs.h>
#include <gui/IConsumerListener.h>
#include <gui/IGraphicBufferConsumer.h>
#include <gui/OccupancyTracker.h>
-
#include <ui/PixelFormat.h>
-
#include <utils/String8.h>
#include <utils/Vector.h>
#include <utils/threads.h>
-
namespace android {
// ----------------------------------------------------------------------------
@@ -81,7 +79,13 @@
void setFrameAvailableListener(const wp<FrameAvailableListener>& listener);
// See IGraphicBufferConsumer::detachBuffer
- status_t detachBuffer(int slot);
+ status_t detachBuffer(int slot) __attribute((
+ deprecated("Please use the GraphicBuffer variant--slots are deprecated.")));
+
+#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)
+ // See IGraphicBufferConsumer::detachBuffer
+ status_t detachBuffer(const sp<GraphicBuffer>& buffer);
+#endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)
// See IGraphicBufferConsumer::setDefaultBufferSize
status_t setDefaultBufferSize(uint32_t width, uint32_t height);
@@ -150,6 +154,10 @@
virtual void onBuffersReleased() override;
virtual void onSidebandStreamChanged() override;
+ virtual int getSlotForBufferLocked(const sp<GraphicBuffer>& buffer);
+
+ virtual status_t detachBufferLocked(int slotIndex);
+
// freeBufferLocked frees up the given buffer slot. If the slot has been
// initialized this will release the reference to the GraphicBuffer in that
// slot. Otherwise it has no effect.
diff --git a/libs/gui/include/gui/Surface.h b/libs/gui/include/gui/Surface.h
index d07e121..3e2aa47 100644
--- a/libs/gui/include/gui/Surface.h
+++ b/libs/gui/include/gui/Surface.h
@@ -34,6 +34,8 @@
#include <shared_mutex>
#include <unordered_set>
+#include <com_android_graphics_libgui_flags.h>
+
namespace android {
class GraphicBuffer;
@@ -60,6 +62,10 @@
virtual void onBuffersDiscarded(const std::vector<sp<GraphicBuffer>>& buffers) = 0;
virtual void onBufferDetached(int slot) = 0;
+#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_CONSUMER_ATTACH_CALLBACK)
+ virtual void onBufferAttached() {}
+ virtual bool needsAttachNotify() { return false; }
+#endif
};
class StubSurfaceListener : public SurfaceListener {
@@ -455,6 +461,15 @@
virtual void onBufferDetached(int slot) { mSurfaceListener->onBufferDetached(slot); }
virtual void onBuffersDiscarded(const std::vector<int32_t>& slots);
+#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(BQ_CONSUMER_ATTACH_CALLBACK)
+ virtual void onBufferAttached() {
+ mSurfaceListener->onBufferAttached();
+ }
+
+ virtual bool needsAttachNotify() {
+ return mSurfaceListener->needsAttachNotify();
+ }
+#endif
private:
wp<Surface> mParent;
sp<SurfaceListener> mSurfaceListener;
diff --git a/libs/gui/tests/BufferItemConsumer_test.cpp b/libs/gui/tests/BufferItemConsumer_test.cpp
index 6880678..7d33f28 100644
--- a/libs/gui/tests/BufferItemConsumer_test.cpp
+++ b/libs/gui/tests/BufferItemConsumer_test.cpp
@@ -17,10 +17,12 @@
#define LOG_TAG "BufferItemConsumer_test"
//#define LOG_NDEBUG 0
+#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <gui/BufferItemConsumer.h>
#include <gui/IProducerListener.h>
#include <gui/Surface.h>
+#include <ui/GraphicBuffer.h>
namespace android {
@@ -42,6 +44,17 @@
BufferItemConsumerTest* mTest;
};
+ struct TrackingProducerListener : public BnProducerListener {
+ TrackingProducerListener(BufferItemConsumerTest* test) : mTest(test) {}
+
+ virtual void onBufferReleased() override {}
+ virtual bool needsReleaseNotify() override { return true; }
+ virtual void onBuffersDiscarded(const std::vector<int32_t>&) override {}
+ virtual void onBufferDetached(int slot) override { mTest->HandleBufferDetached(slot); }
+
+ BufferItemConsumerTest* mTest;
+ };
+
void SetUp() override {
BufferQueue::createBufferQueue(&mProducer, &mConsumer);
mBIC =
@@ -51,7 +64,7 @@
mBFL = new BufferFreedListener(this);
mBIC->setBufferFreedListener(mBFL);
- sp<IProducerListener> producerListener = new StubProducerListener();
+ sp<IProducerListener> producerListener = new TrackingProducerListener(this);
IGraphicBufferProducer::QueueBufferOutput bufferOutput;
ASSERT_EQ(NO_ERROR,
mProducer->connect(producerListener, NATIVE_WINDOW_API_CPU,
@@ -71,6 +84,13 @@
ALOGD("HandleBufferFreed, mFreedBufferCount=%d", mFreedBufferCount);
}
+ void HandleBufferDetached(int slot) {
+ std::lock_guard<std::mutex> lock(mMutex);
+ mDetachedBufferSlots.push_back(slot);
+ ALOGD("HandleBufferDetached, slot=%d mDetachedBufferSlots-count=%zu", slot,
+ mDetachedBufferSlots.size());
+ }
+
void DequeueBuffer(int* outSlot) {
ASSERT_NE(outSlot, nullptr);
@@ -120,6 +140,7 @@
std::mutex mMutex;
int mFreedBufferCount{0};
+ std::vector<int> mDetachedBufferSlots = {};
sp<BufferItemConsumer> mBIC;
sp<BufferFreedListener> mBFL;
@@ -203,4 +224,19 @@
ASSERT_EQ(1, GetFreedBufferCount());
}
+#if COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)
+// Test that delete BufferItemConsumer triggers onBufferFreed.
+TEST_F(BufferItemConsumerTest, DetachBufferWithBuffer) {
+ int slot;
+ // Let buffer go through the cycle at least once.
+ DequeueBuffer(&slot);
+ QueueBuffer(slot);
+ AcquireBuffer(&slot);
+
+ sp<GraphicBuffer> buffer = mBuffers[slot];
+ EXPECT_EQ(OK, mBIC->detachBuffer(buffer));
+ EXPECT_THAT(mDetachedBufferSlots, testing::ElementsAre(slot));
+}
+#endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)
+
} // namespace android
diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp
index 8d6917f..ee0c555 100644
--- a/libs/gui/tests/Surface_test.cpp
+++ b/libs/gui/tests/Surface_test.cpp
@@ -23,12 +23,17 @@
#include <android/gui/IDisplayEventConnection.h>
#include <android/gui/ISurfaceComposer.h>
#include <android/hardware/configstore/1.0/ISurfaceFlingerConfigs.h>
+#include <android/hardware_buffer.h>
#include <binder/ProcessState.h>
#include <com_android_graphics_libgui_flags.h>
#include <configstore/Utils.h>
#include <gui/AidlStatusUtil.h>
#include <gui/BufferItemConsumer.h>
+#include <gui/BufferQueue.h>
#include <gui/CpuConsumer.h>
+#include <gui/IConsumerListener.h>
+#include <gui/IGraphicBufferConsumer.h>
+#include <gui/IGraphicBufferProducer.h>
#include <gui/ISurfaceComposer.h>
#include <gui/Surface.h>
#include <gui/SurfaceComposerClient.h>
@@ -36,6 +41,7 @@
#include <private/gui/ComposerService.h>
#include <private/gui/ComposerServiceAIDL.h>
#include <sys/types.h>
+#include <system/window.h>
#include <ui/BufferQueueDefs.h>
#include <ui/DisplayMode.h>
#include <ui/GraphicBuffer.h>
@@ -2312,6 +2318,76 @@
EXPECT_EQ(OK, surface->allowAllocation(true));
EXPECT_EQ(OK, surface->dequeueBuffer(&buffer, &fence));
}
+
+TEST_F(SurfaceTest, QueueAcquireReleaseDequeue_CalledInStack_DoesNotDeadlock) {
+ class DequeuingSurfaceListener : public SurfaceListener {
+ public:
+ DequeuingSurfaceListener(const wp<Surface>& surface) : mSurface(surface) {}
+
+ virtual void onBufferReleased() override {
+ sp<Surface> surface = mSurface.promote();
+ ASSERT_NE(nullptr, surface);
+ EXPECT_EQ(OK, surface->dequeueBuffer(&mBuffer, &mFence));
+ }
+
+ virtual bool needsReleaseNotify() override { return true; }
+ virtual void onBuffersDiscarded(const std::vector<sp<GraphicBuffer>>&) override {}
+ virtual void onBufferDetached(int) override {}
+
+ sp<GraphicBuffer> mBuffer;
+ sp<Fence> mFence;
+
+ private:
+ wp<Surface> mSurface;
+ };
+
+ class ImmediateReleaseConsumerListener : public BufferItemConsumer::FrameAvailableListener {
+ public:
+ ImmediateReleaseConsumerListener(const wp<BufferItemConsumer>& consumer)
+ : mConsumer(consumer) {}
+
+ virtual void onFrameAvailable(const BufferItem&) override {
+ sp<BufferItemConsumer> consumer = mConsumer.promote();
+ ASSERT_NE(nullptr, consumer);
+
+ mCalls += 1;
+
+ BufferItem buffer;
+ EXPECT_EQ(OK, consumer->acquireBuffer(&buffer, 0));
+ EXPECT_EQ(OK, consumer->releaseBuffer(buffer));
+ }
+
+ size_t mCalls = 0;
+
+ private:
+ wp<BufferItemConsumer> mConsumer;
+ };
+
+ sp<IGraphicBufferProducer> bqProducer;
+ sp<IGraphicBufferConsumer> bqConsumer;
+ BufferQueue::createBufferQueue(&bqProducer, &bqConsumer);
+
+ sp<BufferItemConsumer> consumer = sp<BufferItemConsumer>::make(bqConsumer, 3);
+ sp<Surface> surface = sp<Surface>::make(bqProducer);
+ sp<ImmediateReleaseConsumerListener> consumerListener =
+ sp<ImmediateReleaseConsumerListener>::make(consumer);
+ consumer->setFrameAvailableListener(consumerListener);
+
+ sp<DequeuingSurfaceListener> surfaceListener = sp<DequeuingSurfaceListener>::make(surface);
+ EXPECT_EQ(OK, surface->connect(NATIVE_WINDOW_API_CPU, false, surfaceListener));
+
+ EXPECT_EQ(OK, surface->setMaxDequeuedBufferCount(2));
+
+ sp<GraphicBuffer> buffer;
+ sp<Fence> fence;
+ EXPECT_EQ(OK, surface->dequeueBuffer(&buffer, &fence));
+ EXPECT_EQ(OK, surface->queueBuffer(buffer, fence));
+
+ EXPECT_EQ(1u, consumerListener->mCalls);
+ EXPECT_NE(nullptr, surfaceListener->mBuffer);
+
+ EXPECT_EQ(OK, surface->disconnect(NATIVE_WINDOW_API_CPU));
+}
#endif // COM_ANDROID_GRAPHICS_LIBGUI_FLAGS(WB_PLATFORM_API_IMPROVEMENTS)
} // namespace android
diff --git a/services/inputflinger/TEST_MAPPING b/services/inputflinger/TEST_MAPPING
index 018de5d..82a93f7 100644
--- a/services/inputflinger/TEST_MAPPING
+++ b/services/inputflinger/TEST_MAPPING
@@ -152,6 +152,9 @@
},
{
"name": "CtsSurfaceControlTests"
+ },
+ {
+ "name": "WmTests"
}
],
"postsubmit": [
@@ -293,6 +296,9 @@
},
{
"name": "monkey_test"
+ },
+ {
+ "name": "WmTests"
}
],
"staged-platinum-postsubmit": [