Merge changes Ida17429b,I3debc83d,If68332d6 into main
* changes:
InputVerifier: make action_button a field of the action enum
InputVerifier: use `let ... else` when converting flags and buttons
InputVerifier: put parameters into a struct
diff --git a/cmds/flatland/Main.cpp b/cmds/flatland/Main.cpp
index 6d14d56..277300d 100644
--- a/cmds/flatland/Main.cpp
+++ b/cmds/flatland/Main.cpp
@@ -772,8 +772,8 @@
break;
case 'i':
- displayId = DisplayId::fromValue<PhysicalDisplayId>(atoll(optarg));
- if (!displayId) {
+ displayId = PhysicalDisplayId::fromValue(atoll(optarg));
+ if (std::find(ids.begin(), ids.end(), displayId) == ids.end()) {
fprintf(stderr, "Invalid display ID: %s.\n", optarg);
exit(4);
}
diff --git a/include/ftl/small_map.h b/include/ftl/small_map.h
index 83d5967..96d35cd 100644
--- a/include/ftl/small_map.h
+++ b/include/ftl/small_map.h
@@ -234,6 +234,12 @@
//
bool erase(const key_type& key) { return erase(key, begin()); }
+ // Removes a mapping.
+ //
+ // The last() and end() iterators, as well as those to the erased mapping, are invalidated.
+ //
+ void erase(iterator it) { map_.unstable_erase(it); }
+
// Removes all mappings.
//
// All iterators are invalidated.
diff --git a/libs/binder/IActivityManager.cpp b/libs/binder/IActivityManager.cpp
index 152c815..83f4719 100644
--- a/libs/binder/IActivityManager.cpp
+++ b/libs/binder/IActivityManager.cpp
@@ -147,9 +147,11 @@
data.writeInterfaceToken(IActivityManager::getInterfaceDescriptor());
data.writeInt32(uid);
data.writeString16(callingPackage);
- remote()->transact(IS_UID_ACTIVE_TRANSACTION, data, &reply);
+ status_t err = remote()->transact(IS_UID_ACTIVE_TRANSACTION, data, &reply);
// fail on exception
- if (reply.readExceptionCode() != 0) return false;
+ if (err != NO_ERROR || ((err = reply.readExceptionCode()) != NO_ERROR)) {
+ return false;
+ }
return reply.readInt32() == 1;
}
@@ -159,9 +161,9 @@
data.writeInterfaceToken(IActivityManager::getInterfaceDescriptor());
data.writeInt32(uid);
data.writeString16(callingPackage);
- remote()->transact(GET_UID_PROCESS_STATE_TRANSACTION, data, &reply);
+ status_t err = remote()->transact(GET_UID_PROCESS_STATE_TRANSACTION, data, &reply);
// fail on exception
- if (reply.readExceptionCode() != 0) {
+ if (err != NO_ERROR || ((err = reply.readExceptionCode()) != NO_ERROR)) {
return ActivityManager::PROCESS_STATE_UNKNOWN;
}
return reply.readInt32();
@@ -192,7 +194,7 @@
data.writeInt32(appPid);
status_t err = remote()->transact(LOG_FGS_API_BEGIN_TRANSACTION, data, &reply,
IBinder::FLAG_ONEWAY);
- if (err != NO_ERROR || ((err = reply.readExceptionCode()) != NO_ERROR)) {
+ if (err != NO_ERROR) {
ALOGD("%s: FGS Logger Transaction failed, %d", __func__, err);
return err;
}
@@ -207,7 +209,7 @@
data.writeInt32(appPid);
status_t err =
remote()->transact(LOG_FGS_API_END_TRANSACTION, data, &reply, IBinder::FLAG_ONEWAY);
- if (err != NO_ERROR || ((err = reply.readExceptionCode()) != NO_ERROR)) {
+ if (err != NO_ERROR) {
ALOGD("%s: FGS Logger Transaction failed, %d", __func__, err);
return err;
}
@@ -224,7 +226,7 @@
data.writeInt32(appPid);
status_t err = remote()->transact(LOG_FGS_API_STATE_CHANGED_TRANSACTION, data, &reply,
IBinder::FLAG_ONEWAY);
- if (err != NO_ERROR || ((err = reply.readExceptionCode()) != NO_ERROR)) {
+ if (err != NO_ERROR) {
ALOGD("%s: FGS Logger Transaction failed, %d", __func__, err);
return err;
}
diff --git a/libs/binder/include/binder/IInterface.h b/libs/binder/include/binder/IInterface.h
index bb45ad2..993ad82 100644
--- a/libs/binder/include/binder/IInterface.h
+++ b/libs/binder/include/binder/IInterface.h
@@ -263,7 +263,6 @@
"android.utils.IMemory",
"android.utils.IMemoryHeap",
"com.android.car.procfsinspector.IProcfsInspector",
- "com.android.internal.app.IAppOpsCallback",
"com.android.internal.app.IAppOpsService",
"com.android.internal.app.IBatteryStats",
"com.android.internal.os.IResultReceiver",
diff --git a/libs/binder/rust/rpcbinder/Android.bp b/libs/binder/rust/rpcbinder/Android.bp
index 4036551..46651ce 100644
--- a/libs/binder/rust/rpcbinder/Android.bp
+++ b/libs/binder/rust/rpcbinder/Android.bp
@@ -26,6 +26,7 @@
],
visibility: [
"//device/google/cuttlefish/shared/minidroid/sample",
+ "//hardware/interfaces/security/see:__subpackages__",
"//packages/modules/Virtualization:__subpackages__",
],
apex_available: [
diff --git a/libs/binder/tests/binderAllocationLimits.cpp b/libs/binder/tests/binderAllocationLimits.cpp
index c0c0aae..339ce4b 100644
--- a/libs/binder/tests/binderAllocationLimits.cpp
+++ b/libs/binder/tests/binderAllocationLimits.cpp
@@ -22,17 +22,33 @@
#include <binder/RpcServer.h>
#include <binder/RpcSession.h>
#include <cutils/trace.h>
+#include <gtest/gtest-spi.h>
#include <gtest/gtest.h>
#include <utils/CallStack.h>
#include <malloc.h>
+#include <atomic>
#include <functional>
+#include <numeric>
#include <vector>
using namespace android::binder::impl;
static android::String8 gEmpty(""); // make sure first allocation from optimization runs
+struct State {
+ State(std::vector<size_t>&& expectedMallocs) : expectedMallocs(std::move(expectedMallocs)) {}
+ ~State() {
+ size_t num = numMallocs.load();
+ if (expectedMallocs.size() != num) {
+ ADD_FAILURE() << "Expected " << expectedMallocs.size() << " allocations, but got "
+ << num;
+ }
+ }
+ const std::vector<size_t> expectedMallocs;
+ std::atomic<size_t> numMallocs;
+};
+
struct DestructionAction {
DestructionAction(std::function<void()> f) : mF(std::move(f)) {}
~DestructionAction() { mF(); };
@@ -95,8 +111,7 @@
// Action to execute when malloc is hit. Supports nesting. Malloc is not
// restricted when the allocation hook is being processed.
-__attribute__((warn_unused_result))
-DestructionAction OnMalloc(LambdaHooks::AllocationHook f) {
+__attribute__((warn_unused_result)) DestructionAction OnMalloc(LambdaHooks::AllocationHook f) {
MallocHooks before = MallocHooks::save();
LambdaHooks::lambdas.emplace_back(std::move(f));
LambdaHooks::lambda_malloc_hooks.overwrite();
@@ -106,6 +121,22 @@
});
}
+DestructionAction setExpectedMallocs(std::vector<size_t>&& expected) {
+ auto state = std::make_shared<State>(std::move(expected));
+ return OnMalloc([state = state](size_t bytes) {
+ size_t num = state->numMallocs.fetch_add(1);
+ if (num >= state->expectedMallocs.size() || state->expectedMallocs[num] != bytes) {
+ ADD_FAILURE() << "Unexpected allocation number " << num << " of size " << bytes
+ << " bytes" << std::endl
+ << android::CallStack::stackToString("UNEXPECTED ALLOCATION",
+ android::CallStack::getCurrent(
+ 4 /*ignoreDepth*/)
+ .get())
+ << std::endl;
+ }
+ });
+}
+
// exported symbol, to force compiler not to optimize away pointers we set here
const void* imaginary_use;
@@ -119,16 +150,53 @@
imaginary_use = new int[10];
}
+ delete[] reinterpret_cast<const int*>(imaginary_use);
EXPECT_EQ(mallocs, 1u);
}
+TEST(TestTheTest, OnMallocWithExpectedMallocs) {
+ std::vector<size_t> expectedMallocs = {
+ 4,
+ 16,
+ 8,
+ };
+ {
+ const auto on_malloc = setExpectedMallocs(std::move(expectedMallocs));
+ imaginary_use = new int32_t[1];
+ delete[] reinterpret_cast<const int*>(imaginary_use);
+ imaginary_use = new int32_t[4];
+ delete[] reinterpret_cast<const int*>(imaginary_use);
+ imaginary_use = new int32_t[2];
+ delete[] reinterpret_cast<const int*>(imaginary_use);
+ }
+}
+
+TEST(TestTheTest, OnMallocWithExpectedMallocsWrongSize) {
+ std::vector<size_t> expectedMallocs = {
+ 4,
+ 16,
+ 100000,
+ };
+ EXPECT_NONFATAL_FAILURE(
+ {
+ const auto on_malloc = setExpectedMallocs(std::move(expectedMallocs));
+ imaginary_use = new int32_t[1];
+ delete[] reinterpret_cast<const int*>(imaginary_use);
+ imaginary_use = new int32_t[4];
+ delete[] reinterpret_cast<const int*>(imaginary_use);
+ imaginary_use = new int32_t[2];
+ delete[] reinterpret_cast<const int*>(imaginary_use);
+ },
+ "Unexpected allocation number 2 of size 8 bytes");
+}
__attribute__((warn_unused_result))
DestructionAction ScopeDisallowMalloc() {
return OnMalloc([&](size_t bytes) {
- ADD_FAILURE() << "Unexpected allocation: " << bytes;
+ FAIL() << "Unexpected allocation: " << bytes;
using android::CallStack;
- std::cout << CallStack::stackToString("UNEXPECTED ALLOCATION", CallStack::getCurrent(4 /*ignoreDepth*/).get())
+ std::cout << CallStack::stackToString("UNEXPECTED ALLOCATION",
+ CallStack::getCurrent(4 /*ignoreDepth*/).get())
<< std::endl;
});
}
@@ -224,6 +292,51 @@
EXPECT_EQ(mallocs, 1u);
}
+TEST(BinderAccessorAllocation, AddAccessorCheckService) {
+ // Need to call defaultServiceManager() before checking malloc because it
+ // will allocate an instance in the call_once
+ const auto sm = defaultServiceManager();
+ const std::string kInstanceName1 = "foo.bar.IFoo/default";
+ const std::string kInstanceName2 = "foo.bar.IFoo2/default";
+ const String16 kInstanceName16(kInstanceName1.c_str());
+ std::vector<size_t> expectedMallocs = {
+ // addAccessorProvider
+ 112, // new AccessorProvider
+ 16, // new AccessorProviderEntry
+ // checkService
+ 45, // String8 from String16 in CppShim::checkService
+ 128, // writeInterfaceToken
+ 16, // getInjectedAccessor, new AccessorProviderEntry
+ 66, // getInjectedAccessor, String16
+ 45, // String8 from String16 in AccessorProvider::provide
+ };
+ std::set<std::string> supportedInstances = {kInstanceName1, kInstanceName2};
+ auto onMalloc = setExpectedMallocs(std::move(expectedMallocs));
+
+ auto receipt =
+ android::addAccessorProvider(std::move(supportedInstances),
+ [&](const String16&) -> sp<IBinder> { return nullptr; });
+ EXPECT_FALSE(receipt.expired());
+
+ sp<IBinder> binder = sm->checkService(kInstanceName16);
+
+ status_t status = android::removeAccessorProvider(receipt);
+}
+
+TEST(BinderAccessorAllocation, AddAccessorEmpty) {
+ std::vector<size_t> expectedMallocs = {
+ 48, // From ALOGE with empty set of instances
+ };
+ std::set<std::string> supportedInstances = {};
+ auto onMalloc = setExpectedMallocs(std::move(expectedMallocs));
+
+ auto receipt =
+ android::addAccessorProvider(std::move(supportedInstances),
+ [&](const String16&) -> sp<IBinder> { return nullptr; });
+
+ EXPECT_TRUE(receipt.expired());
+}
+
TEST(RpcBinderAllocation, SetupRpcServer) {
std::string tmp = getenv("TMPDIR") ?: "/tmp";
std::string addr = tmp + "/binderRpcBenchmark";
@@ -255,6 +368,7 @@
}
int main(int argc, char** argv) {
+ LOG(INFO) << "Priming static log variables for binderAllocationLimits.";
if (getenv("LIBC_HOOKS_ENABLE") == nullptr) {
CHECK(0 == setenv("LIBC_HOOKS_ENABLE", "1", true /*overwrite*/));
execv(argv[0], argv);
diff --git a/libs/binder/tests/binderStabilityIntegrationTest.cpp b/libs/binder/tests/binderStabilityIntegrationTest.cpp
index a3fc9cc..cbc4180 100644
--- a/libs/binder/tests/binderStabilityIntegrationTest.cpp
+++ b/libs/binder/tests/binderStabilityIntegrationTest.cpp
@@ -47,6 +47,7 @@
Stability::Level level = Stability::Level::UNDECLARED;
switch (partition) {
+ case Partition::PRODUCT:
case Partition::SYSTEM:
case Partition::SYSTEM_EXT:
level = Stability::Level::SYSTEM;
diff --git a/libs/debugstore/rust/src/core.rs b/libs/debugstore/rust/src/core.rs
index a8acded..16147dd 100644
--- a/libs/debugstore/rust/src/core.rs
+++ b/libs/debugstore/rust/src/core.rs
@@ -48,7 +48,7 @@
///
/// This constant is used as a part of the debug store's data format,
/// allowing for version tracking and compatibility checks.
- const ENCODE_VERSION: u32 = 2;
+ const ENCODE_VERSION: u32 = 3;
/// Creates a new instance of `DebugStore` with specified event limit and maximum delay.
fn new() -> Self {
@@ -123,9 +123,11 @@
impl fmt::Display for DebugStore {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ // Write the debug store header information
let uptime_now = uptimeMillis();
write!(f, "{},{},{}::", Self::ENCODE_VERSION, self.event_store.len(), uptime_now)?;
+ // Join events with a separator
write!(
f,
"{}",
@@ -136,7 +138,10 @@
acc.push_str(&event.to_string());
acc
})
- )
+ )?;
+
+ // Write the debug store footer
+ write!(f, ";;")
}
}
diff --git a/libs/gui/BLASTBufferQueue.cpp b/libs/gui/BLASTBufferQueue.cpp
index 0848fac..c770db9 100644
--- a/libs/gui/BLASTBufferQueue.cpp
+++ b/libs/gui/BLASTBufferQueue.cpp
@@ -415,14 +415,12 @@
stat.frameEventStats.dequeueReadyTime);
}
auto currFrameNumber = stat.frameEventStats.frameNumber;
- std::vector<ReleaseCallbackId> staleReleases;
- for (const auto& [key, value]: mSubmitted) {
- if (currFrameNumber > key.framenumber) {
- staleReleases.push_back(key);
+ // Release stale buffers.
+ for (const auto& [key, _] : mSubmitted) {
+ if (currFrameNumber <= key.framenumber) {
+ continue; // not stale.
}
- }
- for (const auto& staleRelease : staleReleases) {
- releaseBufferCallbackLocked(staleRelease,
+ releaseBufferCallbackLocked(key,
stat.previousReleaseFence
? stat.previousReleaseFence
: Fence::NO_FENCE,
@@ -618,7 +616,7 @@
mNumAcquired++;
mLastAcquiredFrameNumber = bufferItem.mFrameNumber;
ReleaseCallbackId releaseCallbackId(buffer->getId(), mLastAcquiredFrameNumber);
- mSubmitted[releaseCallbackId] = bufferItem;
+ mSubmitted.emplace_or_replace(releaseCallbackId, bufferItem);
bool needsDisconnect = false;
mBufferItemConsumer->getConnectionEvents(bufferItem.mFrameNumber, &needsDisconnect);
@@ -851,7 +849,7 @@
void BLASTBufferQueue::onFrameDequeued(const uint64_t bufferId) {
std::lock_guard _lock{mTimestampMutex};
- mDequeueTimestamps[bufferId] = systemTime();
+ mDequeueTimestamps.emplace_or_replace(bufferId, systemTime());
};
void BLASTBufferQueue::onFrameCancelled(const uint64_t bufferId) {
diff --git a/libs/gui/Choreographer.cpp b/libs/gui/Choreographer.cpp
index ba50bf8..ab747b9 100644
--- a/libs/gui/Choreographer.cpp
+++ b/libs/gui/Choreographer.cpp
@@ -238,7 +238,7 @@
// socket should be atomic across processes.
DisplayEventReceiver::Event event;
event.header =
- DisplayEventReceiver::Event::Header{DisplayEventReceiver::DISPLAY_EVENT_NULL,
+ DisplayEventReceiver::Event::Header{DisplayEventType::DISPLAY_EVENT_NULL,
PhysicalDisplayId::fromPort(0), systemTime()};
injectEvent(event);
}
diff --git a/libs/gui/DisplayEventDispatcher.cpp b/libs/gui/DisplayEventDispatcher.cpp
index 68f10f4..6f23885 100644
--- a/libs/gui/DisplayEventDispatcher.cpp
+++ b/libs/gui/DisplayEventDispatcher.cpp
@@ -167,7 +167,7 @@
for (ssize_t i = 0; i < n; i++) {
const DisplayEventReceiver::Event& ev = buf[i];
switch (ev.header.type) {
- case DisplayEventReceiver::DISPLAY_EVENT_VSYNC:
+ case DisplayEventType::DISPLAY_EVENT_VSYNC:
// Later vsync events will just overwrite the info from earlier
// ones. That's fine, we only care about the most recent.
gotVsync = true;
@@ -183,7 +183,7 @@
ATRACE_INT("RenderRate", fps);
}
break;
- case DisplayEventReceiver::DISPLAY_EVENT_HOTPLUG:
+ case DisplayEventType::DISPLAY_EVENT_HOTPLUG:
if (ev.hotplug.connectionError == 0) {
dispatchHotplug(ev.header.timestamp, ev.header.displayId,
ev.hotplug.connected);
@@ -192,31 +192,28 @@
ev.hotplug.connectionError);
}
break;
- case DisplayEventReceiver::DISPLAY_EVENT_MODE_CHANGE:
+ case DisplayEventType::DISPLAY_EVENT_MODE_CHANGE:
dispatchModeChanged(ev.header.timestamp, ev.header.displayId,
ev.modeChange.modeId, ev.modeChange.vsyncPeriod);
break;
- case DisplayEventReceiver::DISPLAY_EVENT_NULL:
+ case DisplayEventType::DISPLAY_EVENT_NULL:
dispatchNullEvent(ev.header.timestamp, ev.header.displayId);
break;
- case DisplayEventReceiver::DISPLAY_EVENT_FRAME_RATE_OVERRIDE:
+ case DisplayEventType::DISPLAY_EVENT_FRAME_RATE_OVERRIDE:
mFrameRateOverrides.emplace_back(ev.frameRateOverride);
break;
- case DisplayEventReceiver::DISPLAY_EVENT_FRAME_RATE_OVERRIDE_FLUSH:
+ case DisplayEventType::DISPLAY_EVENT_FRAME_RATE_OVERRIDE_FLUSH:
dispatchFrameRateOverrides(ev.header.timestamp, ev.header.displayId,
std::move(mFrameRateOverrides));
break;
- case DisplayEventReceiver::DISPLAY_EVENT_HDCP_LEVELS_CHANGE:
+ case DisplayEventType::DISPLAY_EVENT_HDCP_LEVELS_CHANGE:
dispatchHdcpLevelsChanged(ev.header.displayId,
ev.hdcpLevelsChange.connectedLevel,
ev.hdcpLevelsChange.maxLevel);
break;
- case DisplayEventReceiver::DISPLAY_EVENT_MODE_REJECTION:
+ case DisplayEventType::DISPLAY_EVENT_MODE_REJECTION:
dispatchModeRejected(ev.header.displayId, ev.modeRejection.modeId);
break;
- default:
- ALOGW("dispatcher %p ~ ignoring unknown event type %#x", this, ev.header.type);
- break;
}
}
}
diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp
index 44aac9b..ebfc62f 100644
--- a/libs/gui/LayerState.cpp
+++ b/libs/gui/LayerState.cpp
@@ -67,7 +67,6 @@
reserved(0),
cornerRadius(0.0f),
clientDrawnCornerRadius(0.0f),
- clientDrawnShadowRadius(0.0f),
backgroundBlurRadius(0),
color(0),
bufferTransform(0),
@@ -143,7 +142,6 @@
SAFE_PARCEL(output.write, colorTransform.asArray(), 16 * sizeof(float));
SAFE_PARCEL(output.writeFloat, cornerRadius);
SAFE_PARCEL(output.writeFloat, clientDrawnCornerRadius);
- SAFE_PARCEL(output.writeFloat, clientDrawnShadowRadius);
SAFE_PARCEL(output.writeUint32, backgroundBlurRadius);
SAFE_PARCEL(output.writeParcelable, metadata);
SAFE_PARCEL(output.writeFloat, bgColor.r);
@@ -279,7 +277,6 @@
SAFE_PARCEL(input.read, &colorTransform, 16 * sizeof(float));
SAFE_PARCEL(input.readFloat, &cornerRadius);
SAFE_PARCEL(input.readFloat, &clientDrawnCornerRadius);
- SAFE_PARCEL(input.readFloat, &clientDrawnShadowRadius);
SAFE_PARCEL(input.readUint32, &backgroundBlurRadius);
SAFE_PARCEL(input.readParcelable, &metadata);
@@ -606,10 +603,6 @@
what |= eClientDrawnCornerRadiusChanged;
clientDrawnCornerRadius = other.clientDrawnCornerRadius;
}
- if (other.what & eClientDrawnShadowsChanged) {
- what |= eClientDrawnShadowsChanged;
- clientDrawnShadowRadius = other.clientDrawnShadowRadius;
- }
if (other.what & eBackgroundBlurRadiusChanged) {
what |= eBackgroundBlurRadiusChanged;
backgroundBlurRadius = other.backgroundBlurRadius;
@@ -824,7 +817,6 @@
CHECK_DIFF(diff, eLayerStackChanged, other, layerStack);
CHECK_DIFF(diff, eCornerRadiusChanged, other, cornerRadius);
CHECK_DIFF(diff, eClientDrawnCornerRadiusChanged, other, clientDrawnCornerRadius);
- CHECK_DIFF(diff, eClientDrawnShadowsChanged, other, clientDrawnShadowRadius);
CHECK_DIFF(diff, eBackgroundBlurRadiusChanged, other, backgroundBlurRadius);
if (other.what & eBlurRegionsChanged) diff |= eBlurRegionsChanged;
if (other.what & eRelativeLayerChanged) {
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index 852885b..37ed23b 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -1415,9 +1415,8 @@
ComposerServiceAIDL::getComposerService()->getPhysicalDisplayIds(&displayIds);
if (status.isOk()) {
physicalDisplayIds.reserve(displayIds.size());
- for (auto item : displayIds) {
- auto id = DisplayId::fromValue<PhysicalDisplayId>(static_cast<uint64_t>(item));
- physicalDisplayIds.push_back(*id);
+ for (auto id : displayIds) {
+ physicalDisplayIds.push_back(PhysicalDisplayId::fromValue(static_cast<uint64_t>(id)));
}
}
return physicalDisplayIds;
@@ -1688,17 +1687,6 @@
return *this;
}
-SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setClientDrawnShadowRadius(
- const sp<SurfaceControl>& sc, float clientDrawnShadowRadius) {
- layer_state_t* s = getLayerState(sc);
- if (!s) {
- mStatus = BAD_INDEX;
- return *this;
- }
- s->what |= layer_state_t::eClientDrawnShadowsChanged;
- s->clientDrawnShadowRadius = clientDrawnShadowRadius;
- return *this;
-}
SurfaceComposerClient::Transaction& SurfaceComposerClient::Transaction::setBackgroundBlurRadius(
const sp<SurfaceControl>& sc, int backgroundBlurRadius) {
layer_state_t* s = getLayerState(sc);
diff --git a/libs/gui/include/gui/BLASTBufferQueue.h b/libs/gui/include/gui/BLASTBufferQueue.h
index b97a496..cdc2150 100644
--- a/libs/gui/include/gui/BLASTBufferQueue.h
+++ b/libs/gui/include/gui/BLASTBufferQueue.h
@@ -20,6 +20,7 @@
#include <optional>
#include <queue>
+#include <ftl/small_map.h>
#include <gui/BufferItem.h>
#include <gui/BufferItemConsumer.h>
#include <gui/IGraphicBufferConsumer.h>
@@ -36,6 +37,10 @@
namespace android {
+// Sizes determined empirically to avoid allocations during common activity.
+constexpr size_t kSubmittedBuffersMapSizeHint = 8;
+constexpr size_t kDequeueTimestampsMapSizeHint = 32;
+
class BLASTBufferQueue;
class BufferItemConsumer;
@@ -206,7 +211,7 @@
// 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
+ ftl::SmallMap<ReleaseCallbackId, BufferItem, kSubmittedBuffersMapSizeHint> mSubmitted
GUARDED_BY(mMutex);
// Keep a queue of the released buffers instead of immediately releasing
@@ -291,8 +296,8 @@
std::mutex mTimestampMutex;
// Tracks buffer dequeue times by the client. This info is sent to SurfaceFlinger which uses
// it for debugging purposes.
- std::unordered_map<uint64_t /* bufferId */, nsecs_t> mDequeueTimestamps
- GUARDED_BY(mTimestampMutex);
+ ftl::SmallMap<uint64_t /* bufferId */, nsecs_t, kDequeueTimestampsMapSizeHint>
+ mDequeueTimestamps GUARDED_BY(mTimestampMutex);
// Keep track of SurfaceControls that have submitted a transaction and BBQ is waiting on a
// callback for them.
diff --git a/libs/gui/include/gui/DisplayEventReceiver.h b/libs/gui/include/gui/DisplayEventReceiver.h
index ab6a6b7..f51390a 100644
--- a/libs/gui/include/gui/DisplayEventReceiver.h
+++ b/libs/gui/include/gui/DisplayEventReceiver.h
@@ -55,20 +55,20 @@
static_cast<uint32_t>(c4);
}
+enum class DisplayEventType : uint32_t {
+ DISPLAY_EVENT_VSYNC = fourcc('v', 's', 'y', 'n'),
+ DISPLAY_EVENT_HOTPLUG = fourcc('p', 'l', 'u', 'g'),
+ DISPLAY_EVENT_MODE_CHANGE = fourcc('m', 'o', 'd', 'e'),
+ DISPLAY_EVENT_MODE_REJECTION = fourcc('r', 'e', 'j', 'e'),
+ DISPLAY_EVENT_NULL = fourcc('n', 'u', 'l', 'l'),
+ DISPLAY_EVENT_FRAME_RATE_OVERRIDE = fourcc('r', 'a', 't', 'e'),
+ DISPLAY_EVENT_FRAME_RATE_OVERRIDE_FLUSH = fourcc('f', 'l', 's', 'h'),
+ DISPLAY_EVENT_HDCP_LEVELS_CHANGE = fourcc('h', 'd', 'c', 'p'),
+};
+
// ----------------------------------------------------------------------------
class DisplayEventReceiver {
public:
- enum {
- DISPLAY_EVENT_VSYNC = fourcc('v', 's', 'y', 'n'),
- DISPLAY_EVENT_HOTPLUG = fourcc('p', 'l', 'u', 'g'),
- DISPLAY_EVENT_MODE_CHANGE = fourcc('m', 'o', 'd', 'e'),
- DISPLAY_EVENT_MODE_REJECTION = fourcc('r', 'e', 'j', 'e'),
- DISPLAY_EVENT_NULL = fourcc('n', 'u', 'l', 'l'),
- DISPLAY_EVENT_FRAME_RATE_OVERRIDE = fourcc('r', 'a', 't', 'e'),
- DISPLAY_EVENT_FRAME_RATE_OVERRIDE_FLUSH = fourcc('f', 'l', 's', 'h'),
- DISPLAY_EVENT_HDCP_LEVELS_CHANGE = fourcc('h', 'd', 'c', 'p'),
- };
-
struct Event {
// We add __attribute__((aligned(8))) for nsecs_t fields because
// we need to make sure all fields are aligned the same with x86
@@ -77,7 +77,7 @@
// https://en.wikipedia.org/wiki/Data_structure_alignment
struct Header {
- uint32_t type;
+ DisplayEventType type;
PhysicalDisplayId displayId __attribute__((aligned(8)));
nsecs_t timestamp __attribute__((aligned(8)));
};
diff --git a/libs/gui/include/gui/InputTransferToken.h b/libs/gui/include/gui/InputTransferToken.h
index 6530b50..fb4aaa7 100644
--- a/libs/gui/include/gui/InputTransferToken.h
+++ b/libs/gui/include/gui/InputTransferToken.h
@@ -25,7 +25,7 @@
namespace android {
struct InputTransferToken : public RefBase, Parcelable {
public:
- InputTransferToken() { mToken = new BBinder(); }
+ InputTransferToken() { mToken = sp<BBinder>::make(); }
InputTransferToken(const sp<IBinder>& token) { mToken = token; }
@@ -50,4 +50,4 @@
return token1->mToken == token2->mToken;
}
-} // namespace android
\ No newline at end of file
+} // namespace android
diff --git a/libs/gui/include/gui/LayerState.h b/libs/gui/include/gui/LayerState.h
index 1002614..d04b861 100644
--- a/libs/gui/include/gui/LayerState.h
+++ b/libs/gui/include/gui/LayerState.h
@@ -232,7 +232,6 @@
ePictureProfileHandleChanged = 0x80000'00000000,
eAppContentPriorityChanged = 0x100000'00000000,
eClientDrawnCornerRadiusChanged = 0x200000'00000000,
- eClientDrawnShadowsChanged = 0x400000'00000000,
};
layer_state_t();
@@ -276,7 +275,7 @@
layer_state_t::eColorSpaceAgnosticChanged | layer_state_t::eColorTransformChanged |
layer_state_t::eCornerRadiusChanged | layer_state_t::eDimmingEnabledChanged |
layer_state_t::eHdrMetadataChanged | layer_state_t::eShadowRadiusChanged |
- layer_state_t::eClientDrawnShadowsChanged | layer_state_t::eStretchChanged |
+ layer_state_t::eStretchChanged |
layer_state_t::ePictureProfileHandleChanged | layer_state_t::eAppContentPriorityChanged;
// Changes which invalidates the layer's visible region in CE.
@@ -336,7 +335,6 @@
matrix22_t matrix;
float cornerRadius;
float clientDrawnCornerRadius;
- float clientDrawnShadowRadius;
uint32_t backgroundBlurRadius;
sp<SurfaceControl> relativeLayerSurfaceControl;
diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h
index d30a830..10225cc 100644
--- a/libs/gui/include/gui/SurfaceComposerClient.h
+++ b/libs/gui/include/gui/SurfaceComposerClient.h
@@ -569,10 +569,6 @@
// radius is drawn by the client and not SurfaceFlinger.
Transaction& setClientDrawnCornerRadius(const sp<SurfaceControl>& sc,
float clientDrawnCornerRadius);
- // Sets the client drawn shadow radius for the layer. This indicates that the shadows
- // are drawn by the client and not SurfaceFlinger.
- Transaction& setClientDrawnShadowRadius(const sp<SurfaceControl>& sc,
- float clientDrawnShadowRadius);
Transaction& setBackgroundBlurRadius(const sp<SurfaceControl>& sc,
int backgroundBlurRadius);
Transaction& setBlurRegions(const sp<SurfaceControl>& sc,
diff --git a/libs/gui/tests/RegionSampling_test.cpp b/libs/gui/tests/RegionSampling_test.cpp
index a0d8c53..c35efe2 100644
--- a/libs/gui/tests/RegionSampling_test.cpp
+++ b/libs/gui/tests/RegionSampling_test.cpp
@@ -40,7 +40,7 @@
std::unique_lock<decltype(mutex_)> lk(mutex_);
auto check_event = [](auto const& ev) -> bool {
- return ev.header.type == DisplayEventReceiver::DISPLAY_EVENT_VSYNC;
+ return ev.header.type == DisplayEventType::DISPLAY_EVENT_VSYNC;
};
DisplayEventReceiver::Event ev_;
int evs = receiver_.getEvents(&ev_, 1);
diff --git a/libs/permission/Android.bp b/libs/permission/Android.bp
index 0eeca54..929f067 100644
--- a/libs/permission/Android.bp
+++ b/libs/permission/Android.bp
@@ -16,6 +16,7 @@
double_loadable: true,
srcs: [
"aidl/android/content/AttributionSourceState.aidl",
+ "aidl/com/android/internal/app/IAppOpsCallback.aidl",
"aidl/android/permission/IPermissionChecker.aidl",
],
}
@@ -36,7 +37,6 @@
],
srcs: [
"AppOpsManager.cpp",
- "IAppOpsCallback.cpp",
"IAppOpsService.cpp",
"android/permission/PermissionChecker.cpp",
],
diff --git a/libs/permission/IAppOpsCallback.cpp b/libs/permission/IAppOpsCallback.cpp
deleted file mode 100644
index 2b3f462..0000000
--- a/libs/permission/IAppOpsCallback.cpp
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2013 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 "AppOpsCallback"
-
-#include <binder/IAppOpsCallback.h>
-
-#include <utils/Log.h>
-#include <binder/Parcel.h>
-#include <utils/String8.h>
-
-namespace android {
-
-// ----------------------------------------------------------------------
-
-class BpAppOpsCallback : public BpInterface<IAppOpsCallback>
-{
-public:
- explicit BpAppOpsCallback(const sp<IBinder>& impl)
- : BpInterface<IAppOpsCallback>(impl)
- {
- }
-
- virtual void opChanged(int32_t op, const String16& packageName) {
- Parcel data, reply;
- data.writeInterfaceToken(IAppOpsCallback::getInterfaceDescriptor());
- data.writeInt32(op);
- data.writeString16(packageName);
- remote()->transact(OP_CHANGED_TRANSACTION, data, &reply, IBinder::FLAG_ONEWAY);
- }
-};
-
-IMPLEMENT_META_INTERFACE(AppOpsCallback, "com.android.internal.app.IAppOpsCallback")
-
-// ----------------------------------------------------------------------
-
-// NOLINTNEXTLINE(google-default-arguments)
-status_t BnAppOpsCallback::onTransact(
- uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
-{
- switch(code) {
- case OP_CHANGED_TRANSACTION: {
- CHECK_INTERFACE(IAppOpsCallback, data, reply);
- int32_t op = data.readInt32();
- String16 packageName;
- (void)data.readString16(&packageName);
- opChanged(op, packageName);
- return NO_ERROR;
- } break;
- default:
- return BBinder::onTransact(code, data, reply, flags);
- }
-}
-
-} // namespace android
diff --git a/services/surfaceflinger/RenderArea.cpp b/libs/permission/aidl/com/android/internal/app/IAppOpsCallback.aidl
similarity index 61%
rename from services/surfaceflinger/RenderArea.cpp
rename to libs/permission/aidl/com/android/internal/app/IAppOpsCallback.aidl
index 5fea521..36b19df 100644
--- a/services/surfaceflinger/RenderArea.cpp
+++ b/libs/permission/aidl/com/android/internal/app/IAppOpsCallback.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright 2017 The Android Open Source Project
+ * Copyright (C) 2025 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,18 +14,8 @@
* limitations under the License.
*/
-#include "RenderArea.h"
+package com.android.internal.app;
-namespace android {
-
-float RenderArea::getCaptureFillValue(CaptureFill captureFill) {
- switch(captureFill) {
- case CaptureFill::CLEAR:
- return 0.0f;
- case CaptureFill::OPAQUE:
- default:
- return 1.0f;
- }
+oneway interface IAppOpsCallback {
+ void opChanged(int op, int uid, String packageName, String persistentDeviceId);
}
-
-} // namespace android
diff --git a/libs/permission/include/binder/AppOpsManager.h b/libs/permission/include/binder/AppOpsManager.h
index 7e179d6..a22c975 100644
--- a/libs/permission/include/binder/AppOpsManager.h
+++ b/libs/permission/include/binder/AppOpsManager.h
@@ -180,10 +180,10 @@
void finishOp(int32_t op, int32_t uid, const String16& callingPackage,
const std::optional<String16>& attributionTag);
void startWatchingMode(int32_t op, const String16& packageName,
- const sp<IAppOpsCallback>& callback);
+ const sp<com::android::internal::app::IAppOpsCallback>& callback);
void startWatchingMode(int32_t op, const String16& packageName, int32_t flags,
- const sp<IAppOpsCallback>& callback);
- void stopWatchingMode(const sp<IAppOpsCallback>& callback);
+ const sp<com::android::internal::app::IAppOpsCallback>& callback);
+ void stopWatchingMode(const sp<com::android::internal::app::IAppOpsCallback>& callback);
int32_t permissionToOpCode(const String16& permission);
void setCameraAudioRestriction(int32_t mode);
diff --git a/libs/permission/include/binder/IAppOpsCallback.h b/libs/permission/include/binder/IAppOpsCallback.h
deleted file mode 100644
index eb76f57..0000000
--- a/libs/permission/include/binder/IAppOpsCallback.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2013 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
-
-#ifndef __ANDROID_VNDK__
-
-#include <binder/IInterface.h>
-
-namespace android {
-
-// ----------------------------------------------------------------------
-
-class IAppOpsCallback : public IInterface
-{
-public:
- DECLARE_META_INTERFACE(AppOpsCallback)
-
- virtual void opChanged(int32_t op, const String16& packageName) = 0;
-
- enum {
- OP_CHANGED_TRANSACTION = IBinder::FIRST_CALL_TRANSACTION
- };
-};
-
-// ----------------------------------------------------------------------
-
-class BnAppOpsCallback : public BnInterface<IAppOpsCallback>
-{
-public:
- // NOLINTNEXTLINE(google-default-arguments)
- virtual status_t onTransact( uint32_t code,
- const Parcel& data,
- Parcel* reply,
- uint32_t flags = 0);
-};
-
-// ----------------------------------------------------------------------
-
-} // namespace android
-
-#else // __ANDROID_VNDK__
-#error "This header is not visible to vendors"
-#endif // __ANDROID_VNDK__
diff --git a/libs/permission/include/binder/IAppOpsService.h b/libs/permission/include/binder/IAppOpsService.h
index 918fcdb..1468fd9 100644
--- a/libs/permission/include/binder/IAppOpsService.h
+++ b/libs/permission/include/binder/IAppOpsService.h
@@ -16,7 +16,8 @@
#pragma once
-#include <binder/IAppOpsCallback.h>
+#include <com/android/internal/app/IAppOpsCallback.h>
+#include <com/android/internal/app/BnAppOpsCallback.h>
#include <binder/IInterface.h>
#include <optional>
@@ -27,6 +28,8 @@
namespace android {
+using IAppOpsCallback = ::com::android::internal::app::IAppOpsCallback;
+
// ----------------------------------------------------------------------
class IAppOpsService : public IInterface
diff --git a/libs/renderengine/OWNERS b/libs/renderengine/OWNERS
index 17ab29f..e296283 100644
--- a/libs/renderengine/OWNERS
+++ b/libs/renderengine/OWNERS
@@ -7,4 +7,3 @@
lpy@google.com
nscobie@google.com
sallyqi@google.com
-scroggo@google.com
diff --git a/libs/renderengine/skia/filters/KawaseBlurDualFilter.cpp b/libs/renderengine/skia/filters/KawaseBlurDualFilter.cpp
index 897f5cf..ff96b08 100644
--- a/libs/renderengine/skia/filters/KawaseBlurDualFilter.cpp
+++ b/libs/renderengine/skia/filters/KawaseBlurDualFilter.cpp
@@ -39,12 +39,36 @@
namespace skia {
KawaseBlurDualFilter::KawaseBlurDualFilter() : BlurFilter() {
- // A shader to sample each vertex of a unit regular heptagon
- // plus the original fragment coordinate.
- SkString blurString(R"(
+ // A shader to sample each vertex of a square, plus the original fragment coordinate,
+ // using a total of 5 samples.
+ SkString lowSampleBlurString(R"(
uniform shader child;
uniform float in_blurOffset;
uniform float in_crossFade;
+ uniform float in_weightedCrossFade;
+
+ const float2 STEP_0 = float2( 0.707106781, 0.707106781);
+ const float2 STEP_1 = float2( 0.707106781, -0.707106781);
+ const float2 STEP_2 = float2(-0.707106781, -0.707106781);
+ const float2 STEP_3 = float2(-0.707106781, 0.707106781);
+
+ half4 main(float2 xy) {
+ half3 c = child.eval(xy).rgb;
+
+ c += child.eval(xy + STEP_0 * in_blurOffset).rgb;
+ c += child.eval(xy + STEP_1 * in_blurOffset).rgb;
+ c += child.eval(xy + STEP_2 * in_blurOffset).rgb;
+ c += child.eval(xy + STEP_3 * in_blurOffset).rgb;
+
+ return half4(c * in_weightedCrossFade, in_crossFade);
+ }
+ )");
+
+ // A shader to sample each vertex of a unit regular heptagon, plus the original fragment
+ // coordinate, using a total of 8 samples.
+ SkString highSampleBlurString(R"(
+ uniform shader child;
+ uniform float in_blurOffset;
const float2 STEP_0 = float2( 1.0, 0.0);
const float2 STEP_1 = float2( 0.623489802, 0.781831482);
@@ -65,39 +89,46 @@
c += child.eval(xy + STEP_5 * in_blurOffset).rgb;
c += child.eval(xy + STEP_6 * in_blurOffset).rgb;
- return half4(c * 0.125 * in_crossFade, in_crossFade);
+ return half4(c * 0.125, 1.0);
}
)");
- auto [blurEffect, error] = SkRuntimeEffect::MakeForShader(blurString);
- LOG_ALWAYS_FATAL_IF(!blurEffect, "RuntimeShader error: %s", error.c_str());
- mBlurEffect = std::move(blurEffect);
+ auto [lowSampleBlurEffect, error] = SkRuntimeEffect::MakeForShader(lowSampleBlurString);
+ auto [highSampleBlurEffect, error2] = SkRuntimeEffect::MakeForShader(highSampleBlurString);
+ LOG_ALWAYS_FATAL_IF(!lowSampleBlurEffect, "RuntimeShader error: %s", error.c_str());
+ LOG_ALWAYS_FATAL_IF(!highSampleBlurEffect, "RuntimeShader error: %s", error2.c_str());
+ mLowSampleBlurEffect = std::move(lowSampleBlurEffect);
+ mHighSampleBlurEffect = std::move(highSampleBlurEffect);
}
void KawaseBlurDualFilter::blurInto(const sk_sp<SkSurface>& drawSurface,
const sk_sp<SkImage>& readImage, const float radius,
- const float alpha) const {
+ const float alpha,
+ const sk_sp<SkRuntimeEffect>& blurEffect) const {
const float scale = static_cast<float>(drawSurface->width()) / readImage->width();
SkMatrix blurMatrix = SkMatrix::Scale(scale, scale);
blurInto(drawSurface,
readImage->makeShader(SkTileMode::kClamp, SkTileMode::kClamp,
SkSamplingOptions(SkFilterMode::kLinear, SkMipmapMode::kNone),
blurMatrix),
- readImage->width() / static_cast<float>(drawSurface->width()), radius, alpha);
+ radius, alpha, blurEffect);
}
void KawaseBlurDualFilter::blurInto(const sk_sp<SkSurface>& drawSurface, sk_sp<SkShader> input,
- const float inverseScale, const float radius,
- const float alpha) const {
+ const float radius, const float alpha,
+ const sk_sp<SkRuntimeEffect>& blurEffect) const {
SkPaint paint;
if (radius == 0) {
paint.setShader(std::move(input));
paint.setAlphaf(alpha);
} else {
- SkRuntimeShaderBuilder blurBuilder(mBlurEffect);
+ SkRuntimeShaderBuilder blurBuilder(blurEffect);
blurBuilder.child("child") = std::move(input);
+ if (blurEffect == mLowSampleBlurEffect) {
+ blurBuilder.uniform("in_crossFade") = alpha;
+ blurBuilder.uniform("in_weightedCrossFade") = alpha * 0.2f;
+ }
blurBuilder.uniform("in_blurOffset") = radius;
- blurBuilder.uniform("in_crossFade") = alpha;
paint.setShader(blurBuilder.makeShader(nullptr));
}
paint.setBlendMode(alpha == 1.0f ? SkBlendMode::kSrc : SkBlendMode::kSrcOver);
@@ -163,16 +194,19 @@
input->makeShader(SkTileMode::kClamp, SkTileMode::kClamp,
SkSamplingOptions(SkFilterMode::kLinear, SkMipmapMode::kNone),
blurMatrix);
- blurInto(surfaces[0], std::move(sourceShader), kInputScale, kWeights[0] * step, 1.0f);
+ blurInto(surfaces[0], std::move(sourceShader), kWeights[0] * step, 1.0f,
+ mLowSampleBlurEffect);
}
// Next the remaining downscale blur passes.
for (int i = 0; i < filterPasses; i++) {
- blurInto(surfaces[i + 1], surfaces[i]->makeTemporaryImage(), kWeights[1 + i] * step, 1.0f);
+ // Blur with the higher sample effect into the smaller buffers, for better visual quality.
+ blurInto(surfaces[i + 1], surfaces[i]->makeTemporaryImage(), kWeights[1 + i] * step, 1.0f,
+ i == 0 ? mLowSampleBlurEffect : mHighSampleBlurEffect);
}
// Finally blur+upscale back to our original size.
for (int i = filterPasses - 1; i >= 0; i--) {
blurInto(surfaces[i], surfaces[i + 1]->makeTemporaryImage(), kWeights[4 - i] * step,
- std::min(1.0f, filterDepth - i));
+ std::min(1.0f, filterDepth - i), mLowSampleBlurEffect);
}
return surfaces[0]->makeTemporaryImage();
}
diff --git a/libs/renderengine/skia/filters/KawaseBlurDualFilter.h b/libs/renderengine/skia/filters/KawaseBlurDualFilter.h
index 6f4adbf..5efda35 100644
--- a/libs/renderengine/skia/filters/KawaseBlurDualFilter.h
+++ b/libs/renderengine/skia/filters/KawaseBlurDualFilter.h
@@ -41,13 +41,14 @@
const sk_sp<SkImage> blurInput, const SkRect& blurRect) const override;
private:
- sk_sp<SkRuntimeEffect> mBlurEffect;
+ sk_sp<SkRuntimeEffect> mLowSampleBlurEffect;
+ sk_sp<SkRuntimeEffect> mHighSampleBlurEffect;
void blurInto(const sk_sp<SkSurface>& drawSurface, const sk_sp<SkImage>& readImage,
- const float radius, const float alpha) const;
+ const float radius, const float alpha, const sk_sp<SkRuntimeEffect>&) const;
void blurInto(const sk_sp<SkSurface>& drawSurface, const sk_sp<SkShader> input,
- const float inverseScale, const float radius, const float alpha) const;
+ const float radius, const float alpha, const sk_sp<SkRuntimeEffect>&) const;
};
} // namespace skia
diff --git a/libs/renderengine/skia/filters/LutShader.cpp b/libs/renderengine/skia/filters/LutShader.cpp
index 10218bb..f262158 100644
--- a/libs/renderengine/skia/filters/LutShader.cpp
+++ b/libs/renderengine/skia/filters/LutShader.cpp
@@ -182,8 +182,8 @@
* (R1, G1, B1, 0)
* ...
*/
- SkImageInfo info = SkImageInfo::Make(length /* the number of rgba */ * 4, 1,
- kRGBA_F16_SkColorType, kPremul_SkAlphaType);
+ SkImageInfo info = SkImageInfo::Make(length /* the number of rgba */, 1, kRGBA_F16_SkColorType,
+ kPremul_SkAlphaType);
SkBitmap bitmap;
bitmap.allocPixels(info);
if (!bitmap.installPixels(info, buffer.data(), info.minRowBytes())) {
diff --git a/libs/shaders/OWNERS b/libs/shaders/OWNERS
index 6d91da3..6977a49 100644
--- a/libs/shaders/OWNERS
+++ b/libs/shaders/OWNERS
@@ -1,4 +1,3 @@
alecmouri@google.com
jreck@google.com
sallyqi@google.com
-scroggo@google.com
\ No newline at end of file
diff --git a/libs/tonemap/OWNERS b/libs/tonemap/OWNERS
index 6d91da3..6977a49 100644
--- a/libs/tonemap/OWNERS
+++ b/libs/tonemap/OWNERS
@@ -1,4 +1,3 @@
alecmouri@google.com
jreck@google.com
sallyqi@google.com
-scroggo@google.com
\ No newline at end of file
diff --git a/libs/ui/DisplayIdentification.cpp b/libs/ui/DisplayIdentification.cpp
index b7ef9b3..78e84fc 100644
--- a/libs/ui/DisplayIdentification.cpp
+++ b/libs/ui/DisplayIdentification.cpp
@@ -444,7 +444,7 @@
(edid.hashedBlockZeroSerialNumberOpt.value_or(0) >> 11) ^
(edid.hashedDescriptorBlockSerialNumberOpt.value_or(0) << 23);
- return PhysicalDisplayId::fromEdidHash(id);
+ return PhysicalDisplayId::fromValue(id);
}
} // namespace android
diff --git a/libs/ui/OWNERS b/libs/ui/OWNERS
index a0b5fe7..2a85a4b 100644
--- a/libs/ui/OWNERS
+++ b/libs/ui/OWNERS
@@ -2,6 +2,5 @@
alecmouri@google.com
chrisforbes@google.com
jreck@google.com
-lpy@google.com
mathias@google.com
romainguy@google.com
diff --git a/libs/ui/include/ui/DisplayId.h b/libs/ui/include/ui/DisplayId.h
index 13ed754..937e3f1 100644
--- a/libs/ui/include/ui/DisplayId.h
+++ b/libs/ui/include/ui/DisplayId.h
@@ -30,27 +30,16 @@
// Flag indicating that the display is virtual.
static constexpr uint64_t FLAG_VIRTUAL = 1ULL << 63;
- // TODO(b/162612135) Remove default constructor
+ // TODO: b/162612135 - Remove default constructor.
DisplayId() = default;
constexpr DisplayId(const DisplayId&) = default;
DisplayId& operator=(const DisplayId&) = default;
+ static constexpr DisplayId fromValue(uint64_t value) { return DisplayId(value); }
constexpr bool isVirtual() const { return value & FLAG_VIRTUAL; }
uint64_t value;
- // For deserialization.
- static constexpr std::optional<DisplayId> fromValue(uint64_t);
-
- // As above, but also upcast to Id.
- template <typename Id>
- static constexpr std::optional<Id> fromValue(uint64_t value) {
- if (const auto id = Id::tryCast(DisplayId(value))) {
- return id;
- }
- return {};
- }
-
protected:
explicit constexpr DisplayId(uint64_t id) : value(id) {}
};
@@ -74,6 +63,9 @@
// DisplayId of a physical display, such as the internal display or externally connected display.
struct PhysicalDisplayId : DisplayId {
+ // TODO: b/162612135 - Remove default constructor.
+ PhysicalDisplayId() = default;
+
static constexpr ftl::Optional<PhysicalDisplayId> tryCast(DisplayId id) {
if (id.isVirtual()) {
return std::nullopt;
@@ -87,11 +79,6 @@
return PhysicalDisplayId(FLAG_STABLE, port, manufacturerId, modelHash);
}
- // Returns a stable and consistent ID based exclusively on EDID information.
- static constexpr PhysicalDisplayId fromEdidHash(uint64_t hashedEdid) {
- return PhysicalDisplayId(hashedEdid);
- }
-
// Returns an unstable ID. If EDID is available using "fromEdid" is preferred.
static constexpr PhysicalDisplayId fromPort(uint8_t port) {
constexpr uint16_t kManufacturerId = 0;
@@ -99,8 +86,9 @@
return PhysicalDisplayId(0, port, kManufacturerId, kModelHash);
}
- // TODO(b/162612135) Remove default constructor
- PhysicalDisplayId() = default;
+ static constexpr PhysicalDisplayId fromValue(uint64_t value) {
+ return PhysicalDisplayId(value);
+ }
constexpr uint8_t getPort() const { return static_cast<uint8_t>(value); }
@@ -131,8 +119,15 @@
return std::nullopt;
}
+ static constexpr VirtualDisplayId fromValue(uint64_t value) {
+ return VirtualDisplayId(SkipVirtualFlag{}, value);
+ }
+
protected:
+ struct SkipVirtualFlag {};
+ constexpr VirtualDisplayId(SkipVirtualFlag, uint64_t value) : DisplayId(value) {}
explicit constexpr VirtualDisplayId(uint64_t value) : DisplayId(FLAG_VIRTUAL | value) {}
+
explicit constexpr VirtualDisplayId(DisplayId other) : DisplayId(other) {}
};
@@ -146,8 +141,12 @@
return std::nullopt;
}
+ static constexpr HalVirtualDisplayId fromValue(uint64_t value) {
+ return HalVirtualDisplayId(SkipVirtualFlag{}, value);
+ }
+
private:
- explicit constexpr HalVirtualDisplayId(DisplayId other) : VirtualDisplayId(other) {}
+ using VirtualDisplayId::VirtualDisplayId;
};
struct GpuVirtualDisplayId : VirtualDisplayId {
@@ -160,8 +159,12 @@
return std::nullopt;
}
+ static constexpr GpuVirtualDisplayId fromValue(uint64_t value) {
+ return GpuVirtualDisplayId(SkipVirtualFlag{}, value);
+ }
+
private:
- explicit constexpr GpuVirtualDisplayId(DisplayId other) : VirtualDisplayId(other) {}
+ using VirtualDisplayId::VirtualDisplayId;
};
// HalDisplayId is the ID of a display which is managed by HWC.
@@ -177,20 +180,13 @@
return HalDisplayId(id);
}
+ static constexpr HalDisplayId fromValue(uint64_t value) { return HalDisplayId(value); }
+
private:
+ using DisplayId::DisplayId;
explicit constexpr HalDisplayId(DisplayId other) : DisplayId(other) {}
};
-constexpr std::optional<DisplayId> DisplayId::fromValue(uint64_t value) {
- if (const auto id = fromValue<PhysicalDisplayId>(value)) {
- return id;
- }
- if (const auto id = fromValue<VirtualDisplayId>(value)) {
- return id;
- }
- return {};
-}
-
static_assert(sizeof(DisplayId) == sizeof(uint64_t));
static_assert(sizeof(HalDisplayId) == sizeof(uint64_t));
static_assert(sizeof(VirtualDisplayId) == sizeof(uint64_t));
diff --git a/libs/ui/include/ui/ShadowSettings.h b/libs/ui/include/ui/ShadowSettings.h
index 06be6db..c0b83b8 100644
--- a/libs/ui/include/ui/ShadowSettings.h
+++ b/libs/ui/include/ui/ShadowSettings.h
@@ -46,9 +46,6 @@
// Length of the cast shadow. If length is <= 0.f no shadows will be drawn.
float length = 0.f;
- // Length of the cast shadow that is drawn by the client.
- float clientDrawnLength = 0.f;
-
// If true fill in the casting layer is translucent and the shadow needs to fill the bounds.
// Otherwise the shadow will only be drawn around the edges of the casting layer.
bool casterIsTranslucent = false;
@@ -58,7 +55,6 @@
return lhs.boundaries == rhs.boundaries && lhs.ambientColor == rhs.ambientColor &&
lhs.spotColor == rhs.spotColor && lhs.lightPos == rhs.lightPos &&
lhs.lightRadius == rhs.lightRadius && lhs.length == rhs.length &&
- lhs.clientDrawnLength == rhs.clientDrawnLength &&
lhs.casterIsTranslucent == rhs.casterIsTranslucent;
}
diff --git a/libs/ui/tests/DisplayId_test.cpp b/libs/ui/tests/DisplayId_test.cpp
index 090d2ee..209acba 100644
--- a/libs/ui/tests/DisplayId_test.cpp
+++ b/libs/ui/tests/DisplayId_test.cpp
@@ -33,7 +33,7 @@
EXPECT_TRUE(HalDisplayId::tryCast(id));
EXPECT_EQ(id, DisplayId::fromValue(id.value));
- EXPECT_EQ(id, DisplayId::fromValue<PhysicalDisplayId>(id.value));
+ EXPECT_EQ(id, PhysicalDisplayId::fromValue(id.value));
}
TEST(DisplayIdTest, createPhysicalIdFromPort) {
@@ -47,7 +47,7 @@
EXPECT_TRUE(HalDisplayId::tryCast(id));
EXPECT_EQ(id, DisplayId::fromValue(id.value));
- EXPECT_EQ(id, DisplayId::fromValue<PhysicalDisplayId>(id.value));
+ EXPECT_EQ(id, PhysicalDisplayId::fromValue(id.value));
}
TEST(DisplayIdTest, createGpuVirtualId) {
@@ -59,7 +59,7 @@
EXPECT_FALSE(HalDisplayId::tryCast(id));
EXPECT_EQ(id, DisplayId::fromValue(id.value));
- EXPECT_EQ(id, DisplayId::fromValue<GpuVirtualDisplayId>(id.value));
+ EXPECT_EQ(id, GpuVirtualDisplayId::fromValue(id.value));
}
TEST(DisplayIdTest, createVirtualIdFromGpuVirtualId) {
@@ -83,7 +83,7 @@
EXPECT_TRUE(HalDisplayId::tryCast(id));
EXPECT_EQ(id, DisplayId::fromValue(id.value));
- EXPECT_EQ(id, DisplayId::fromValue<HalVirtualDisplayId>(id.value));
+ EXPECT_EQ(id, HalVirtualDisplayId::fromValue(id.value));
}
TEST(DisplayIdTest, createVirtualIdFromHalVirtualId) {
diff --git a/opengl/libs/EGL/egl_display.cpp b/opengl/libs/EGL/egl_display.cpp
index 5fe9484..0dd9f19 100644
--- a/opengl/libs/EGL/egl_display.cpp
+++ b/opengl/libs/EGL/egl_display.cpp
@@ -134,6 +134,11 @@
if (cnx->egl.eglGetPlatformDisplay) {
std::vector<EGLAttrib> attrs;
+ // These must have the same lifetime as |attrs|, because |attrs| contains pointers to these
+ // variables.
+ std::vector<const char*> enabled; // ANGLE features to enable
+ std::vector<const char*> disabled; // ANGLE features to disable
+
if (attrib_list) {
for (const EGLAttrib* attr = attrib_list; *attr != EGL_NONE; attr += 2) {
attrs.push_back(attr[0]);
@@ -142,9 +147,6 @@
}
if (graphicsenv_flags::feature_overrides()) {
- std::vector<const char*> enabled; // ANGLE features to enable
- std::vector<const char*> disabled; // ANGLE features to disable
-
// Get the list of ANGLE features to enable from Global.Settings.
const auto& eglFeatures = GraphicsEnv::getInstance().getAngleEglFeatures();
for (const std::string& eglFeature : eglFeatures) {
@@ -154,25 +156,24 @@
// Get the list of ANGLE features to enable/disable from gpuservice.
GraphicsEnv::getInstance().getAngleFeatureOverrides(enabled, disabled);
if (!enabled.empty()) {
- enabled.push_back(0);
+ enabled.push_back(nullptr);
attrs.push_back(EGL_FEATURE_OVERRIDES_ENABLED_ANGLE);
attrs.push_back(reinterpret_cast<EGLAttrib>(enabled.data()));
}
if (!disabled.empty()) {
- disabled.push_back(0);
+ disabled.push_back(nullptr);
attrs.push_back(EGL_FEATURE_OVERRIDES_DISABLED_ANGLE);
attrs.push_back(reinterpret_cast<EGLAttrib>(disabled.data()));
}
} else {
const auto& eglFeatures = GraphicsEnv::getInstance().getAngleEglFeatures();
- std::vector<const char*> features;
- if (eglFeatures.size() > 0) {
+ if (!eglFeatures.empty()) {
for (const std::string& eglFeature : eglFeatures) {
- features.push_back(eglFeature.c_str());
+ enabled.push_back(eglFeature.c_str());
}
- features.push_back(0);
+ enabled.push_back(nullptr);
attrs.push_back(EGL_FEATURE_OVERRIDES_ENABLED_ANGLE);
- attrs.push_back(reinterpret_cast<EGLAttrib>(features.data()));
+ attrs.push_back(reinterpret_cast<EGLAttrib>(enabled.data()));
}
}
diff --git a/opengl/tools/glgen/stubs/egl/eglCreateWindowSurface.cpp b/opengl/tools/glgen/stubs/egl/eglCreateWindowSurface.cpp
index 7c255ed..5ba72af 100644
--- a/opengl/tools/glgen/stubs/egl/eglCreateWindowSurface.cpp
+++ b/opengl/tools/glgen/stubs/egl/eglCreateWindowSurface.cpp
@@ -113,7 +113,7 @@
if (producer == NULL)
goto not_valid_surface;
- window = new android::Surface(producer, true);
+ window = android::sp<android::Surface>::make(producer, true);
if (window == NULL)
goto not_valid_surface;
diff --git a/services/automotive/display/AutomotiveDisplayProxyService.cpp b/services/automotive/display/AutomotiveDisplayProxyService.cpp
index d205231..afa6233 100644
--- a/services/automotive/display/AutomotiveDisplayProxyService.cpp
+++ b/services/automotive/display/AutomotiveDisplayProxyService.cpp
@@ -34,10 +34,8 @@
sp<IBinder> displayToken = nullptr;
sp<SurfaceControl> surfaceControl = nullptr;
if (it == mDisplays.end()) {
- if (const auto displayId = DisplayId::fromValue<PhysicalDisplayId>(id)) {
- displayToken = SurfaceComposerClient::getPhysicalDisplayToken(*displayId);
- }
-
+ displayToken =
+ SurfaceComposerClient::getPhysicalDisplayToken(PhysicalDisplayId::fromValue(id));
if (displayToken == nullptr) {
ALOGE("Given display id, 0x%lX, is invalid.", (unsigned long)id);
return nullptr;
@@ -160,11 +158,8 @@
HwDisplayConfig activeConfig;
HwDisplayState activeState;
- sp<IBinder> displayToken;
- if (const auto displayId = DisplayId::fromValue<PhysicalDisplayId>(id)) {
- displayToken = SurfaceComposerClient::getPhysicalDisplayToken(*displayId);
- }
-
+ sp<IBinder> displayToken =
+ SurfaceComposerClient::getPhysicalDisplayToken(PhysicalDisplayId::fromValue(id));
if (displayToken == nullptr) {
ALOGE("Given display id, 0x%lX, is invalid.", (unsigned long)id);
} else {
@@ -197,4 +192,3 @@
} // namespace automotive
} // namespace frameworks
} // namespace android
-
diff --git a/services/automotive/display/android.frameworks.automotive.display@1.0-service.rc b/services/automotive/display/android.frameworks.automotive.display@1.0-service.rc
index 5c7f344..e96b17a 100644
--- a/services/automotive/display/android.frameworks.automotive.display@1.0-service.rc
+++ b/services/automotive/display/android.frameworks.automotive.display@1.0-service.rc
@@ -2,3 +2,4 @@
class hal
user graphics
group automotive_evs
+ disabled
diff --git a/services/displayservice/DisplayEventReceiver.cpp b/services/displayservice/DisplayEventReceiver.cpp
index 2bb74c2..9927fb6 100644
--- a/services/displayservice/DisplayEventReceiver.cpp
+++ b/services/displayservice/DisplayEventReceiver.cpp
@@ -22,6 +22,7 @@
#include <android/frameworks/displayservice/1.0/BpHwEventCallback.h>
#include <thread>
+#include <ftl/enum.h>
namespace android {
namespace frameworks {
@@ -97,11 +98,11 @@
for (size_t i = 0; i < static_cast<size_t>(n); ++i) {
const FwkReceiver::Event &event = buf[i];
- uint32_t type = event.header.type;
+ android::DisplayEventType type = event.header.type;
uint64_t timestamp = event.header.timestamp;
switch(buf[i].header.type) {
- case FwkReceiver::DISPLAY_EVENT_VSYNC: {
+ case DisplayEventType::DISPLAY_EVENT_VSYNC: {
auto ret = mCallback->onVsync(timestamp, event.vsync.count);
if (!ret.isOk()) {
LOG(ERROR) << "AttachedEvent handleEvent fails on onVsync callback"
@@ -109,7 +110,7 @@
return 0; // remove the callback
}
} break;
- case FwkReceiver::DISPLAY_EVENT_HOTPLUG: {
+ case DisplayEventType::DISPLAY_EVENT_HOTPLUG: {
auto ret = mCallback->onHotplug(timestamp, event.hotplug.connected);
if (!ret.isOk()) {
LOG(ERROR) << "AttachedEvent handleEvent fails on onHotplug callback"
@@ -118,7 +119,8 @@
}
} break;
default: {
- LOG(ERROR) << "AttachedEvent handleEvent unknown type: " << type;
+ LOG(ERROR) << "AttachedEvent handleEvent unknown type: "
+ << ftl::to_underlying(type);
}
}
}
diff --git a/services/displayservice/OWNERS b/services/displayservice/OWNERS
index 7a3e4c2..40164aa 100644
--- a/services/displayservice/OWNERS
+++ b/services/displayservice/OWNERS
@@ -1,2 +1 @@
smoreland@google.com
-lpy@google.com
diff --git a/services/gpuservice/feature_override/Android.bp b/services/gpuservice/feature_override/Android.bp
index cda67f0..3b5407b 100644
--- a/services/gpuservice/feature_override/Android.bp
+++ b/services/gpuservice/feature_override/Android.bp
@@ -34,9 +34,7 @@
"libbase",
"libgraphicsenv",
"liblog",
- ],
- static_libs: [
- "libprotobuf-cpp-lite-ndk",
+ "libprotobuf-cpp-lite",
],
}
diff --git a/services/inputflinger/dispatcher/InputDispatcher.cpp b/services/inputflinger/dispatcher/InputDispatcher.cpp
index c1ddb6a..f42c368 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.cpp
+++ b/services/inputflinger/dispatcher/InputDispatcher.cpp
@@ -798,20 +798,6 @@
return !isFromSource(source, AINPUT_SOURCE_MOUSE);
}
-/**
- * Return true if stylus is currently down anywhere on the specified display, and false otherwise.
- */
-bool isStylusActiveInDisplay(ui::LogicalDisplayId displayId,
- const std::unordered_map<ui::LogicalDisplayId /*displayId*/,
- TouchState>& touchStatesByDisplay) {
- const auto it = touchStatesByDisplay.find(displayId);
- if (it == touchStatesByDisplay.end()) {
- return false;
- }
- const TouchState& state = it->second;
- return state.hasActiveStylus();
-}
-
Result<void> validateWindowInfosUpdate(const gui::WindowInfosUpdate& update) {
std::unordered_set<int32_t> windowIds;
for (const WindowInfo& info : update.windowInfos) {
@@ -1155,9 +1141,7 @@
// If dispatching is frozen, do not process timeouts or try to deliver any new events.
if (mDispatchFrozen) {
- if (DEBUG_FOCUS) {
- ALOGD("Dispatch frozen. Waiting some more.");
- }
+ LOG_IF(DEBUG, DEBUG_FOCUS) << "Dispatch frozen. Waiting some more.";
return;
}
@@ -1350,9 +1334,8 @@
// Alternatively, maybe there's a spy window that could handle this event.
const std::vector<sp<WindowInfoHandle>> touchedSpies =
- mWindowInfos.findTouchedSpyWindowsAt(displayId, x, y, isStylus,
- motionEntry.deviceId,
- mTouchStates.mTouchStatesByDisplay);
+ findTouchedSpyWindowsAt(displayId, x, y, isStylus, motionEntry.deviceId,
+ mWindowInfos);
for (const auto& windowHandle : touchedSpies) {
const std::shared_ptr<Connection> connection =
mConnectionManager.getConnection(windowHandle->getToken());
@@ -1510,16 +1493,16 @@
return outsideTargets;
}
-std::vector<sp<WindowInfoHandle>> InputDispatcher::DispatcherWindowInfo::findTouchedSpyWindowsAt(
+std::vector<sp<WindowInfoHandle>> InputDispatcher::findTouchedSpyWindowsAt(
ui::LogicalDisplayId displayId, float x, float y, bool isStylus, DeviceId deviceId,
- const std::unordered_map<ui::LogicalDisplayId, TouchState>& touchStatesByDisplay) const {
+ const DispatcherWindowInfo& windowInfos) {
// Traverse windows from front to back and gather the touched spy windows.
std::vector<sp<WindowInfoHandle>> spyWindows;
- const auto& windowHandles = getWindowHandlesForDisplay(displayId);
+ const ui::Transform displayTransform = windowInfos.getDisplayTransform(displayId);
+ const auto& windowHandles = windowInfos.getWindowHandlesForDisplay(displayId);
for (const sp<WindowInfoHandle>& windowHandle : windowHandles) {
const WindowInfo& info = *windowHandle->getInfo();
- if (!windowAcceptsTouchAt(info, displayId, x, y, isStylus,
- getDisplayTransform(displayId))) {
+ if (!windowAcceptsTouchAt(info, displayId, x, y, isStylus, displayTransform)) {
// Skip if the pointer is outside of the window.
continue;
}
@@ -1536,9 +1519,8 @@
const char* reason;
switch (dropReason) {
case DropReason::POLICY:
- if (debugInboundEventDetails()) {
- ALOGD("Dropped event because policy consumed it.");
- }
+ LOG_IF(DEBUG, debugInboundEventDetails())
+ << "Dropped event because policy consumed it.";
reason = "inbound event was dropped because the policy consumed it";
break;
case DropReason::DISABLED:
@@ -1652,9 +1634,7 @@
void InputDispatcher::releaseInboundEventLocked(std::shared_ptr<const EventEntry> entry) {
const std::shared_ptr<InjectionState>& injectionState = entry->injectionState;
if (injectionState && injectionState->injectionResult == InputEventInjectionResult::PENDING) {
- if (DEBUG_DISPATCH_CYCLE) {
- ALOGD("Injected inbound event was dropped.");
- }
+ LOG_IF(DEBUG, DEBUG_DISPATCH_CYCLE) << "Injected inbound event was dropped.";
setInjectionResult(*entry, InputEventInjectionResult::FAILED);
}
if (entry == mNextUnblockedEvent) {
@@ -1694,10 +1674,9 @@
bool InputDispatcher::dispatchDeviceResetLocked(nsecs_t currentTime,
const DeviceResetEntry& entry) {
- if (DEBUG_OUTBOUND_EVENT_DETAILS) {
- ALOGD("dispatchDeviceReset - eventTime=%" PRId64 ", deviceId=%d", entry.eventTime,
- entry.deviceId);
- }
+ LOG_IF(DEBUG, DEBUG_OUTBOUND_EVENT_DETAILS)
+ << "dispatchDeviceReset - eventTime=" << entry.eventTime
+ << ", deviceId=" << entry.deviceId;
// Reset key repeating in case a keyboard device was disabled or enabled.
if (mKeyRepeatState.lastKeyEntry && mKeyRepeatState.lastKeyEntry->deviceId == entry.deviceId) {
@@ -1889,9 +1868,8 @@
} else if (entry->action == AKEY_EVENT_ACTION_UP && mKeyRepeatState.lastKeyEntry &&
mKeyRepeatState.lastKeyEntry->deviceId != entry->deviceId) {
// The key on device 'deviceId' is still down, do not stop key repeat
- if (debugInboundEventDetails()) {
- ALOGD("deviceId=%d got KEY_UP as stale", entry->deviceId);
- }
+ LOG_IF(DEBUG, debugInboundEventDetails())
+ << "deviceId=" << entry->deviceId << " got KEY_UP as stale";
} else if (!entry->syntheticRepeat) {
resetKeyRepeatLocked();
}
@@ -1988,25 +1966,24 @@
}
void InputDispatcher::logOutboundKeyDetails(const char* prefix, const KeyEntry& entry) {
- if (DEBUG_OUTBOUND_EVENT_DETAILS) {
- ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%s, "
- "policyFlags=0x%x, action=0x%x, flags=0x%x, keyCode=0x%x, scanCode=0x%x, "
- "metaState=0x%x, repeatCount=%d, downTime=%" PRId64,
- prefix, entry.eventTime, entry.deviceId, entry.source,
- entry.displayId.toString().c_str(), entry.policyFlags, entry.action, entry.flags,
- entry.keyCode, entry.scanCode, entry.metaState, entry.repeatCount, entry.downTime);
- }
+ LOG_IF(DEBUG, DEBUG_OUTBOUND_EVENT_DETAILS)
+ << prefix << "eventTime=" << entry.eventTime << ", deviceId=" << entry.deviceId
+ << ", source=0x" << std::hex << entry.source
+ << ", displayId=" << entry.displayId.toString() << ", policyFlags=0x"
+ << entry.policyFlags << ", action=0x" << entry.action << ", flags=0x" << entry.flags
+ << ", keyCode=0x" << entry.keyCode << ", scanCode=0x" << entry.scanCode
+ << ", metaState=0x" << entry.metaState << ", repeatCount=" << std::dec
+ << entry.repeatCount << ", downTime=" << entry.downTime;
}
void InputDispatcher::dispatchSensorLocked(nsecs_t currentTime,
const std::shared_ptr<const SensorEntry>& entry,
DropReason* dropReason, nsecs_t& nextWakeupTime) {
- if (DEBUG_OUTBOUND_EVENT_DETAILS) {
- ALOGD("notifySensorEvent eventTime=%" PRId64 ", hwTimestamp=%" PRId64 ", deviceId=%d, "
- "source=0x%x, sensorType=%s",
- entry->eventTime, entry->hwTimestamp, entry->deviceId, entry->source,
- ftl::enum_string(entry->sensorType).c_str());
- }
+ LOG_IF(DEBUG, DEBUG_OUTBOUND_EVENT_DETAILS)
+ << "notifySensorEvent eventTime=" << entry->eventTime
+ << ", hwTimestamp=" << entry->hwTimestamp << ", deviceId=" << entry->deviceId
+ << ", source=0x" << std::hex << entry->source << std::dec
+ << ", sensorType=" << ftl::enum_string(entry->sensorType);
auto command = [this, entry]() REQUIRES(mLock) {
scoped_unlock unlock(mLock);
@@ -2020,10 +1997,9 @@
}
bool InputDispatcher::flushSensor(int deviceId, InputDeviceSensorType sensorType) {
- if (DEBUG_OUTBOUND_EVENT_DETAILS) {
- ALOGD("flushSensor deviceId=%d, sensorType=%s", deviceId,
- ftl::enum_string(sensorType).c_str());
- }
+ LOG_IF(DEBUG, DEBUG_OUTBOUND_EVENT_DETAILS)
+ << "flushSensor deviceId=" << deviceId
+ << ", sensorType=" << ftl::enum_string(sensorType).c_str();
{ // acquire lock
std::scoped_lock _l(mLock);
@@ -2193,9 +2169,7 @@
std::shared_ptr<const EventEntry> eventEntry,
const std::vector<InputTarget>& inputTargets) {
ATRACE_CALL();
- if (DEBUG_DISPATCH_CYCLE) {
- ALOGD("dispatchEventToCurrentInputTargets");
- }
+ LOG_IF(DEBUG, DEBUG_DISPATCH_CYCLE) << "dispatchEventToCurrentInputTargets";
processInteractionsLocked(*eventEntry, inputTargets);
@@ -2238,9 +2212,7 @@
}
void InputDispatcher::resetNoFocusedWindowTimeoutLocked() {
- if (DEBUG_FOCUS) {
- ALOGD("Resetting ANR timeouts.");
- }
+ LOG_IF(DEBUG, DEBUG_FOCUS) << "Resetting ANR timeouts.";
// Reset input target wait timeout.
mNoFocusedWindowTimeoutTime = std::nullopt;
@@ -2480,8 +2452,7 @@
}
std::vector<sp<WindowInfoHandle>> newTouchedWindows =
- windowInfos.findTouchedSpyWindowsAt(displayId, x, y, isStylus, entry.deviceId,
- mTouchStatesByDisplay);
+ findTouchedSpyWindowsAt(displayId, x, y, isStylus, entry.deviceId, windowInfos);
if (newTouchedWindowHandle != nullptr) {
// Process the foreground window first so that it is the first to receive the event.
newTouchedWindows.insert(newTouchedWindows.begin(), newTouchedWindowHandle);
@@ -2494,8 +2465,7 @@
}
for (const sp<WindowInfoHandle>& windowHandle : newTouchedWindows) {
- if (!canWindowReceiveMotion(windowHandle, entry, connections, windowInfos,
- mTouchStatesByDisplay)) {
+ if (!canWindowReceiveMotion(windowHandle, entry, connections, windowInfos)) {
continue;
}
@@ -2576,11 +2546,10 @@
// If the pointer is not currently down, then ignore the event.
if (!tempTouchState.isDown(entry.deviceId) &&
maskedAction != AMOTION_EVENT_ACTION_HOVER_EXIT) {
- if (DEBUG_DROPPED_EVENTS_VERBOSE) {
- LOG(INFO) << "Dropping event because the pointer for device " << entry.deviceId
- << " is not down or we previously dropped the pointer down event in "
- << "display " << displayId << ": " << entry.getDescription();
- }
+ LOG_IF(INFO, DEBUG_DROPPED_EVENTS_VERBOSE)
+ << "Dropping event because the pointer for device " << entry.deviceId
+ << " is not down or we previously dropped the pointer down event in display "
+ << displayId << ": " << entry.getDescription();
return injectionError(InputEventInjectionResult::FAILED);
}
@@ -2618,8 +2587,7 @@
// Do not slide events to the window which can not receive motion event
if (newTouchedWindowHandle != nullptr &&
- !canWindowReceiveMotion(newTouchedWindowHandle, entry, connections, windowInfos,
- mTouchStatesByDisplay)) {
+ !canWindowReceiveMotion(newTouchedWindowHandle, entry, connections, windowInfos)) {
newTouchedWindowHandle = nullptr;
}
@@ -3261,10 +3229,9 @@
return;
}
if (windowDisablingUserActivityInfo != nullptr) {
- if (DEBUG_DISPATCH_CYCLE) {
- ALOGD("Not poking user activity: disabled by window '%s'.",
- windowDisablingUserActivityInfo->name.c_str());
- }
+ LOG_IF(DEBUG, DEBUG_DISPATCH_CYCLE)
+ << "Not poking user activity: disabled by window '"
+ << windowDisablingUserActivityInfo->name << "'.";
return;
}
break;
@@ -3278,10 +3245,9 @@
// the apps, like system shortcuts
if (windowDisablingUserActivityInfo != nullptr &&
keyEntry.interceptKeyResult != KeyEntry::InterceptKeyResult::SKIP) {
- if (DEBUG_DISPATCH_CYCLE) {
- ALOGD("Not poking user activity: disabled by window '%s'.",
- windowDisablingUserActivityInfo->name.c_str());
- }
+ LOG_IF(DEBUG, DEBUG_DISPATCH_CYCLE)
+ << "Not poking user activity: disabled by window '"
+ << windowDisablingUserActivityInfo->name << "'.";
return;
}
break;
@@ -3309,22 +3275,19 @@
ATRACE_NAME_IF(ATRACE_ENABLED(),
StringPrintf("prepareDispatchCycleLocked(inputChannel=%s, id=0x%" PRIx32 ")",
connection->getInputChannelName().c_str(), eventEntry->id));
- if (DEBUG_DISPATCH_CYCLE) {
- ALOGD("channel '%s' ~ prepareDispatchCycle - flags=%s, "
- "globalScaleFactor=%f, pointerIds=%s %s",
- connection->getInputChannelName().c_str(), inputTarget.flags.string().c_str(),
- inputTarget.globalScaleFactor, bitsetToString(inputTarget.getPointerIds()).c_str(),
- inputTarget.getPointerInfoString().c_str());
- }
+ LOG_IF(DEBUG, DEBUG_DISPATCH_CYCLE)
+ << "channel '" << connection->getInputChannelName()
+ << "' ~ prepareDispatchCycle - flags=" << inputTarget.flags.string()
+ << ", globalScaleFactor=" << inputTarget.globalScaleFactor
+ << ", pointerIds=" << bitsetToString(inputTarget.getPointerIds()) << " "
+ << inputTarget.getPointerInfoString();
// Skip this event if the connection status is not normal.
// We don't want to enqueue additional outbound events if the connection is broken.
if (connection->status != Connection::Status::NORMAL) {
- if (DEBUG_DISPATCH_CYCLE) {
- ALOGD("channel '%s' ~ Dropping event because the channel status is %s",
- connection->getInputChannelName().c_str(),
- ftl::enum_string(connection->status).c_str());
- }
+ LOG_IF(DEBUG, DEBUG_DISPATCH_CYCLE) << "channel '" << connection->getInputChannelName()
+ << "' ~ Dropping event because the channel status is "
+ << ftl::enum_string(connection->status);
return;
}
@@ -3443,11 +3406,10 @@
if (resolvedAction == AMOTION_EVENT_ACTION_HOVER_MOVE &&
!connection->inputState.isHovering(motionEntry.deviceId, motionEntry.source,
motionEntry.displayId)) {
- if (DEBUG_DISPATCH_CYCLE) {
- LOG(DEBUG) << "channel '" << connection->getInputChannelName().c_str()
- << "' ~ enqueueDispatchEntryLocked: filling in missing hover "
- "enter event";
- }
+ LOG_IF(DEBUG, DEBUG_DISPATCH_CYCLE)
+ << "channel '" << connection->getInputChannelName().c_str()
+ << "' ~ enqueueDispatchEntryLocked: filling in missing hover enter "
+ "event";
resolvedAction = AMOTION_EVENT_ACTION_HOVER_ENTER;
}
@@ -3741,9 +3703,8 @@
ATRACE_NAME_IF(ATRACE_ENABLED(),
StringPrintf("startDispatchCycleLocked(inputChannel=%s)",
connection->getInputChannelName().c_str()));
- if (DEBUG_DISPATCH_CYCLE) {
- ALOGD("channel '%s' ~ startDispatchCycle", connection->getInputChannelName().c_str());
- }
+ LOG_IF(DEBUG, DEBUG_DISPATCH_CYCLE)
+ << "channel '" << connection->getInputChannelName() << "' ~ startDispatchCycle";
while (connection->status == Connection::Status::NORMAL && !connection->outboundQueue.empty()) {
std::unique_ptr<DispatchEntry>& dispatchEntry = connection->outboundQueue.front();
@@ -3758,10 +3719,9 @@
case EventEntry::Type::KEY: {
const KeyEntry& keyEntry = static_cast<const KeyEntry&>(eventEntry);
std::array<uint8_t, 32> hmac = getSignature(keyEntry, *dispatchEntry);
- if (DEBUG_OUTBOUND_EVENT_DETAILS) {
- LOG(INFO) << "Publishing " << *dispatchEntry << " to "
- << connection->getInputChannelName();
- }
+ LOG_IF(INFO, DEBUG_OUTBOUND_EVENT_DETAILS)
+ << "Publishing " << *dispatchEntry << " to "
+ << connection->getInputChannelName();
// Publish the key event.
status = connection->inputPublisher
@@ -3780,10 +3740,9 @@
}
case EventEntry::Type::MOTION: {
- if (DEBUG_OUTBOUND_EVENT_DETAILS) {
- LOG(INFO) << "Publishing " << *dispatchEntry << " to "
- << connection->getInputChannelName();
- }
+ LOG_IF(INFO, DEBUG_OUTBOUND_EVENT_DETAILS)
+ << "Publishing " << *dispatchEntry << " to "
+ << connection->getInputChannelName();
const MotionEntry& motionEntry = static_cast<const MotionEntry&>(eventEntry);
status = publishMotionEvent(*connection, *dispatchEntry);
if (status == BAD_VALUE) {
@@ -3856,11 +3815,10 @@
} else {
// Pipe is full and we are waiting for the app to finish process some events
// before sending more events to it.
- if (DEBUG_DISPATCH_CYCLE) {
- ALOGD("channel '%s' ~ Could not publish event because the pipe is full, "
- "waiting for the application to catch up",
- connection->getInputChannelName().c_str());
- }
+ LOG_IF(DEBUG, DEBUG_DISPATCH_CYCLE)
+ << "channel '" << connection->getInputChannelName()
+ << "' ~ Could not publish event because the pipe is full, waiting for "
+ "the application to catch up";
}
} else {
ALOGE("channel '%s' ~ Could not publish event due to an unexpected error, "
@@ -3926,10 +3884,9 @@
void InputDispatcher::finishDispatchCycleLocked(nsecs_t currentTime,
const std::shared_ptr<Connection>& connection,
uint32_t seq, bool handled, nsecs_t consumeTime) {
- if (DEBUG_DISPATCH_CYCLE) {
- ALOGD("channel '%s' ~ finishDispatchCycle - seq=%u, handled=%s",
- connection->getInputChannelName().c_str(), seq, toString(handled));
- }
+ LOG_IF(DEBUG, DEBUG_DISPATCH_CYCLE)
+ << "channel '" << connection->getInputChannelName()
+ << "' ~ finishDispatchCycle - seq=" << seq << ", handled=" << toString(handled);
if (connection->status != Connection::Status::NORMAL) {
return;
@@ -3944,10 +3901,8 @@
void InputDispatcher::abortBrokenDispatchCycleLocked(const std::shared_ptr<Connection>& connection,
bool notify) {
- if (DEBUG_DISPATCH_CYCLE) {
- LOG(INFO) << "channel '" << connection->getInputChannelName() << "'~ " << __func__
- << " - notify=" << toString(notify);
- }
+ LOG_IF(INFO, DEBUG_DISPATCH_CYCLE) << "channel '" << connection->getInputChannelName() << "'~ "
+ << __func__ << " - notify=" << toString(notify);
// Clear the dispatch queues.
drainDispatchQueue(connection->outboundQueue);
@@ -4072,13 +4027,17 @@
// Generate cancellations for touched windows first. This is to avoid generating cancellations
// through a non-touched window if there are more than one window for an input channel.
if (cancelPointers) {
- for (const auto& [displayId, touchState] : mTouchStates.mTouchStatesByDisplay) {
- if (options.displayId.has_value() && options.displayId != displayId) {
- continue;
- }
- for (const auto& touchedWindow : touchState.windows) {
- synthesizeCancelationEventsForWindowLocked(touchedWindow.windowHandle, options);
- }
+ if (options.displayId.has_value()) {
+ mTouchStates.forAllTouchedWindowsOnDisplay(
+ options.displayId.value(), [&](const sp<gui::WindowInfoHandle>& windowHandle) {
+ base::ScopedLockAssertion assumeLocked(mLock);
+ synthesizeCancelationEventsForWindowLocked(windowHandle, options);
+ });
+ } else {
+ mTouchStates.forAllTouchedWindows([&](const sp<gui::WindowInfoHandle>& windowHandle) {
+ base::ScopedLockAssertion assumeLocked(mLock);
+ synthesizeCancelationEventsForWindowLocked(windowHandle, options);
+ });
}
}
// Follow up by generating cancellations for all windows, because we don't explicitly track
@@ -4149,12 +4108,11 @@
return;
}
- if (DEBUG_OUTBOUND_EVENT_DETAILS) {
- ALOGD("channel '%s' ~ Synthesized %zu cancelation events to bring channel back in sync "
- "with reality: %s, mode=%s.",
- connection->getInputChannelName().c_str(), cancelationEvents.size(), options.reason,
- ftl::enum_string(options.mode).c_str());
- }
+ LOG_IF(DEBUG, DEBUG_OUTBOUND_EVENT_DETAILS)
+ << "channel '" << connection->getInputChannelName() << "' ~ Synthesized "
+ << cancelationEvents.size()
+ << " cancelation events to bring channel back in sync with reality: " << options.reason
+ << ", mode=" << ftl::enum_string(options.mode) << ".";
std::string reason = std::string("reason=").append(options.reason);
android_log_event_list(LOGTAG_INPUT_CANCEL)
@@ -4271,18 +4229,17 @@
return;
}
- if (DEBUG_OUTBOUND_EVENT_DETAILS) {
- ALOGD("channel '%s' ~ Synthesized %zu down events to ensure consistent event stream.",
- connection->getInputChannelName().c_str(), downEvents.size());
- }
+ LOG_IF(DEBUG, DEBUG_OUTBOUND_EVENT_DETAILS)
+ << "channel '" << connection->getInputChannelName() << "' ~ Synthesized "
+ << downEvents.size() << " down events to ensure consistent event stream.";
- const auto [_, touchedWindowState, displayId] =
- findTouchStateWindowAndDisplay(connection->getToken(),
- mTouchStates.mTouchStatesByDisplay);
- if (touchedWindowState == nullptr) {
+ auto touchedWindowHandleAndDisplay =
+ mTouchStates.findTouchedWindowHandleAndDisplay(connection->getToken());
+ if (!touchedWindowHandleAndDisplay.has_value()) {
LOG(FATAL) << __func__ << ": Touch state is out of sync: No touched window for token";
}
- const auto& windowHandle = touchedWindowState->windowHandle;
+
+ const auto [windowHandle, displayId] = touchedWindowHandleAndDisplay.value();
const bool wasEmpty = connection->outboundQueue.empty();
for (std::unique_ptr<EventEntry>& downEventEntry : downEvents) {
@@ -4414,15 +4371,15 @@
}
void InputDispatcher::notifyKey(const NotifyKeyArgs& args) {
- ALOGD_IF(debugInboundEventDetails(),
- "notifyKey - id=%" PRIx32 ", eventTime=%" PRId64
- ", deviceId=%d, source=%s, displayId=%s, policyFlags=0x%x, action=%s, flags=0x%x, "
- "keyCode=%s, scanCode=0x%x, metaState=0x%x, "
- "downTime=%" PRId64,
- args.id, args.eventTime, args.deviceId, inputEventSourceToString(args.source).c_str(),
- args.displayId.toString().c_str(), args.policyFlags,
- KeyEvent::actionToString(args.action), args.flags, KeyEvent::getLabel(args.keyCode),
- args.scanCode, args.metaState, args.downTime);
+ LOG_IF(DEBUG, debugInboundEventDetails())
+ << "notifyKey - id=" << args.id << ", eventTime=" << args.eventTime
+ << ", deviceId=" << args.deviceId
+ << ", source=" << inputEventSourceToString(args.source)
+ << ", displayId=" << args.displayId.toString() << ", policyFlags=0x" << std::hex
+ << args.policyFlags << ", action=" << KeyEvent::actionToString(args.action)
+ << ", flags=0x" << args.flags << ", keyCode=" << KeyEvent::getLabel(args.keyCode)
+ << ", scanCode=0x" << args.scanCode << ", metaState=0x" << args.metaState
+ << ", downTime=" << std::dec << args.downTime;
Result<void> keyCheck = validateKeyEvent(args.action);
if (!keyCheck.ok()) {
LOG(ERROR) << "invalid key event: " << keyCheck.error();
@@ -4632,12 +4589,10 @@
}
void InputDispatcher::notifySensor(const NotifySensorArgs& args) {
- if (debugInboundEventDetails()) {
- ALOGD("notifySensor - id=%" PRIx32 " eventTime=%" PRId64 ", deviceId=%d, source=0x%x, "
- " sensorType=%s",
- args.id, args.eventTime, args.deviceId, args.source,
- ftl::enum_string(args.sensorType).c_str());
- }
+ LOG_IF(DEBUG, debugInboundEventDetails())
+ << "notifySensor - id=" << args.id << " eventTime=" << args.eventTime
+ << ", deviceId=" << args.deviceId << ", source=0x" << std::hex << args.source
+ << std::dec << ", sensorType=" << ftl::enum_string(args.sensorType);
bool needWake = false;
{ // acquire lock
@@ -4659,10 +4614,9 @@
}
void InputDispatcher::notifyVibratorState(const NotifyVibratorStateArgs& args) {
- if (debugInboundEventDetails()) {
- ALOGD("notifyVibratorState - eventTime=%" PRId64 ", device=%d, isOn=%d", args.eventTime,
- args.deviceId, args.isOn);
- }
+ LOG_IF(DEBUG, debugInboundEventDetails())
+ << "notifyVibratorState - eventTime=" << args.eventTime << ", device=" << args.deviceId
+ << ", isOn=" << args.isOn;
mPolicy.notifyVibratorState(args.deviceId, args.isOn);
}
@@ -4671,11 +4625,10 @@
}
void InputDispatcher::notifySwitch(const NotifySwitchArgs& args) {
- if (debugInboundEventDetails()) {
- ALOGD("notifySwitch - eventTime=%" PRId64 ", policyFlags=0x%x, switchValues=0x%08x, "
- "switchMask=0x%08x",
- args.eventTime, args.policyFlags, args.switchValues, args.switchMask);
- }
+ LOG_IF(DEBUG, debugInboundEventDetails())
+ << "notifySwitch - eventTime=" << args.eventTime << ", policyFlags=0x" << std::hex
+ << args.policyFlags << ", switchValues=0x" << std::setfill('0') << std::setw(8)
+ << args.switchValues << ", switchMask=0x" << std::setw(8) << args.switchMask;
uint32_t policyFlags = args.policyFlags;
policyFlags |= POLICY_FLAG_TRUSTED;
@@ -4684,10 +4637,8 @@
void InputDispatcher::notifyDeviceReset(const NotifyDeviceResetArgs& args) {
// TODO(b/308677868) Remove device reset from the InputListener interface
- if (debugInboundEventDetails()) {
- ALOGD("notifyDeviceReset - eventTime=%" PRId64 ", deviceId=%d", args.eventTime,
- args.deviceId);
- }
+ LOG_IF(DEBUG, debugInboundEventDetails())
+ << "notifyDeviceReset - eventTime=" << args.eventTime << ", deviceId=" << args.deviceId;
bool needWake = false;
{ // acquire lock
@@ -4708,10 +4659,9 @@
}
void InputDispatcher::notifyPointerCaptureChanged(const NotifyPointerCaptureChangedArgs& args) {
- if (debugInboundEventDetails()) {
- ALOGD("notifyPointerCaptureChanged - eventTime=%" PRId64 ", enabled=%s", args.eventTime,
- args.request.isEnable() ? "true" : "false");
- }
+ LOG_IF(DEBUG, debugInboundEventDetails())
+ << "notifyPointerCaptureChanged - eventTime=%" << args.eventTime
+ << ", enabled=" << toString(args.request.isEnable());
bool needWake = false;
{ // acquire lock
@@ -4771,12 +4721,10 @@
return InputEventInjectionResult::FAILED;
}
- if (debugInboundEventDetails()) {
- LOG(INFO) << __func__ << ": targetUid=" << toString(targetUid, &uidString)
- << ", syncMode=" << ftl::enum_string(syncMode) << ", timeout=" << timeout.count()
- << "ms, policyFlags=0x" << std::hex << policyFlags << std::dec
- << ", event=" << *event;
- }
+ LOG_IF(INFO, debugInboundEventDetails())
+ << __func__ << ": targetUid=" << toString(targetUid, &uidString)
+ << ", syncMode=" << ftl::enum_string(syncMode) << ", timeout=" << timeout.count()
+ << "ms, policyFlags=0x" << std::hex << policyFlags << std::dec << ", event=" << *event;
nsecs_t endTime = now() + std::chrono::duration_cast<std::chrono::nanoseconds>(timeout).count();
policyFlags |= POLICY_FLAG_INJECTED | POLICY_FLAG_TRUSTED;
@@ -4953,9 +4901,7 @@
bool needWake = false;
while (!injectedEntries.empty()) {
- if (DEBUG_INJECTION) {
- LOG(INFO) << "Injecting " << injectedEntries.front()->getDescription();
- }
+ LOG_IF(INFO, DEBUG_INJECTION) << "Injecting " << injectedEntries.front()->getDescription();
needWake |= enqueueInboundEventLocked(std::move(injectedEntries.front()));
injectedEntries.pop();
}
@@ -4981,10 +4927,8 @@
nsecs_t remainingTimeout = endTime - now();
if (remainingTimeout <= 0) {
- if (DEBUG_INJECTION) {
- ALOGD("injectInputEvent - Timed out waiting for injection result "
- "to become available.");
- }
+ LOG_IF(DEBUG, DEBUG_INJECTION) << "injectInputEvent - Timed out waiting for "
+ "injection result to become available.";
injectionResult = InputEventInjectionResult::TIMED_OUT;
break;
}
@@ -4995,16 +4939,14 @@
if (injectionResult == InputEventInjectionResult::SUCCEEDED &&
syncMode == InputEventInjectionSync::WAIT_FOR_FINISHED) {
while (injectionState->pendingForegroundDispatches != 0) {
- if (DEBUG_INJECTION) {
- ALOGD("injectInputEvent - Waiting for %d pending foreground dispatches.",
- injectionState->pendingForegroundDispatches);
- }
+ LOG_IF(DEBUG, DEBUG_INJECTION) << "injectInputEvent - Waiting for "
+ << injectionState->pendingForegroundDispatches
+ << " pending foreground dispatches.";
nsecs_t remainingTimeout = endTime - now();
if (remainingTimeout <= 0) {
- if (DEBUG_INJECTION) {
- ALOGD("injectInputEvent - Timed out waiting for pending foreground "
- "dispatches to finish.");
- }
+ LOG_IF(DEBUG, DEBUG_INJECTION)
+ << "injectInputEvent - Timed out waiting for pending foreground "
+ "dispatches to finish.";
injectionResult = InputEventInjectionResult::TIMED_OUT;
break;
}
@@ -5015,10 +4957,8 @@
}
} // release lock
- if (DEBUG_INJECTION) {
- LOG(INFO) << "injectInputEvent - Finished with result "
- << ftl::enum_string(injectionResult);
- }
+ LOG_IF(INFO, DEBUG_INJECTION) << "injectInputEvent - Finished with result "
+ << ftl::enum_string(injectionResult);
return injectionResult;
}
@@ -5064,10 +5004,8 @@
}
InjectionState& injectionState = *entry.injectionState;
- if (DEBUG_INJECTION) {
- LOG(INFO) << "Setting input event injection result to "
- << ftl::enum_string(injectionResult);
- }
+ LOG_IF(INFO, DEBUG_INJECTION) << "Setting input event injection result to "
+ << ftl::enum_string(injectionResult);
if (injectionState.injectionIsAsync && !(entry.policyFlags & POLICY_FLAG_FILTERED)) {
// Log the outcome since the injector did not wait for the injection result.
@@ -5273,11 +5211,10 @@
return dump;
}
-bool InputDispatcher::canWindowReceiveMotion(
+bool InputDispatcher::DispatcherTouchState::canWindowReceiveMotion(
const sp<android::gui::WindowInfoHandle>& window,
const android::inputdispatcher::MotionEntry& motionEntry,
- const ConnectionManager& connections, const DispatcherWindowInfo& windowInfos,
- const std::unordered_map<ui::LogicalDisplayId, TouchState>& touchStates) {
+ const ConnectionManager& connections, const DispatcherWindowInfo& windowInfos) const {
const WindowInfo& info = *window->getInfo();
// Skip spy window targets that are not valid for targeted injection.
@@ -5331,7 +5268,7 @@
// Ignore touches if stylus is down anywhere on screen
if (info.inputConfig.test(WindowInfo::InputConfig::GLOBAL_STYLUS_BLOCKS_TOUCH) &&
- isStylusActiveInDisplay(info.displayId, touchStates)) {
+ isStylusActiveInDisplay(info.displayId)) {
LOG(INFO) << "Dropping touch from " << window->getName() << " because stylus is active";
return false;
}
@@ -5495,9 +5432,7 @@
// which might not happen until the next GC.
for (const sp<WindowInfoHandle>& oldWindowHandle : oldWindowHandles) {
if (!mWindowInfos.isWindowPresent(oldWindowHandle)) {
- if (DEBUG_FOCUS) {
- ALOGD("Window went away: %s", oldWindowHandle->getName().c_str());
- }
+ LOG_IF(DEBUG, DEBUG_FOCUS) << "Window went away: " << oldWindowHandle->getName();
oldWindowHandle->releaseChannel();
}
}
@@ -5530,7 +5465,7 @@
LOG(INFO) << "Touched window was removed: " << touchedWindow.windowHandle->getName()
<< " in display %" << displayId;
cancellations.emplace_back(touchedWindow.windowHandle,
- CancelationOptions::Mode::CANCEL_POINTER_EVENTS, std::nullopt);
+ CancelationOptions::Mode::CANCEL_POINTER_EVENTS);
// Since we are about to drop the touch, cancel the events for the wallpaper as well.
if (touchedWindow.targetFlags.test(InputTarget::Flags::FOREGROUND) &&
touchedWindow.windowHandle->getInfo()->inputConfig.test(
@@ -5576,10 +5511,9 @@
void InputDispatcher::setFocusedApplication(
ui::LogicalDisplayId displayId,
const std::shared_ptr<InputApplicationHandle>& inputApplicationHandle) {
- if (DEBUG_FOCUS) {
- ALOGD("setFocusedApplication displayId=%s %s", displayId.toString().c_str(),
- inputApplicationHandle ? inputApplicationHandle->getName().c_str() : "<nullptr>");
- }
+ LOG_IF(DEBUG, DEBUG_FOCUS) << "setFocusedApplication displayId=" << displayId.toString() << " "
+ << (inputApplicationHandle ? inputApplicationHandle->getName()
+ : "<nullptr>");
{ // acquire lock
std::scoped_lock _l(mLock);
setFocusedApplicationLocked(displayId, inputApplicationHandle);
@@ -5629,9 +5563,7 @@
* display. The display-specified events won't be affected.
*/
void InputDispatcher::setFocusedDisplay(ui::LogicalDisplayId displayId) {
- if (DEBUG_FOCUS) {
- ALOGD("setFocusedDisplay displayId=%s", displayId.toString().c_str());
- }
+ LOG_IF(DEBUG, DEBUG_FOCUS) << "setFocusedDisplay displayId=" << displayId.toString();
{ // acquire lock
std::scoped_lock _l(mLock);
ScopedSyntheticEventTracer traceContext(mTracer);
@@ -5685,9 +5617,8 @@
}
void InputDispatcher::setInputDispatchMode(bool enabled, bool frozen) {
- if (DEBUG_FOCUS) {
- ALOGD("setInputDispatchMode: enabled=%d, frozen=%d", enabled, frozen);
- }
+ LOG_IF(DEBUG, DEBUG_FOCUS) << "setInputDispatchMode: enabled=" << enabled
+ << ", frozen=" << frozen;
bool changed;
{ // acquire lock
@@ -5717,9 +5648,7 @@
}
void InputDispatcher::setInputFilterEnabled(bool enabled) {
- if (DEBUG_FOCUS) {
- ALOGD("setInputFilterEnabled: enabled=%d", enabled);
- }
+ LOG_IF(DEBUG, DEBUG_FOCUS) << "setInputFilterEnabled: enabled=" << enabled;
{ // acquire lock
std::scoped_lock _l(mLock);
@@ -5741,14 +5670,16 @@
bool needWake = false;
{
std::scoped_lock lock(mLock);
- ALOGD_IF(DEBUG_TOUCH_MODE,
- "Request to change touch mode to %s (calling pid=%s, uid=%s, "
- "hasPermission=%s, target displayId=%s, mTouchModePerDisplay[displayId]=%s)",
- toString(inTouchMode), pid.toString().c_str(), uid.toString().c_str(),
- toString(hasPermission), displayId.toString().c_str(),
- mTouchModePerDisplay.count(displayId) == 0
- ? "not set"
- : std::to_string(mTouchModePerDisplay[displayId]).c_str());
+ LOG_IF(DEBUG, DEBUG_TOUCH_MODE)
+ << "Request to change touch mode to " << toString(inTouchMode)
+ << " (calling pid=" << pid.toString() << ", uid=" << uid.toString()
+ << ", hasPermission=" << toString(hasPermission)
+ << ", target displayId=" << displayId.toString()
+ << ", mTouchModePerDisplay[displayId]="
+ << (mTouchModePerDisplay.count(displayId) == 0
+ ? "not set"
+ : std::to_string(mTouchModePerDisplay[displayId]))
+ << ")";
auto touchModeIt = mTouchModePerDisplay.find(displayId);
if (touchModeIt != mTouchModePerDisplay.end() && touchModeIt->second == inTouchMode) {
@@ -5798,92 +5729,43 @@
mWindowInfos.setMaximumObscuringOpacityForTouch(opacity);
}
-std::tuple<const TouchState*, const TouchedWindow*, ui::LogicalDisplayId>
-InputDispatcher::findTouchStateWindowAndDisplay(
- const sp<IBinder>& token,
- const std::unordered_map<ui::LogicalDisplayId, TouchState>& touchStatesByDisplay) {
- for (auto& [displayId, state] : touchStatesByDisplay) {
- for (const TouchedWindow& w : state.windows) {
- if (w.windowHandle->getToken() == token) {
- return std::make_tuple(&state, &w, displayId);
- }
- }
- }
- return std::make_tuple(nullptr, nullptr, ui::LogicalDisplayId::DEFAULT);
-}
-
-std::tuple<TouchState*, TouchedWindow*, ui::LogicalDisplayId>
-InputDispatcher::findTouchStateWindowAndDisplay(
- const sp<IBinder>& token,
- std::unordered_map<ui::LogicalDisplayId, TouchState>& touchStatesByDisplay) {
- auto [constTouchState, constTouchedWindow, displayId] = InputDispatcher::
- findTouchStateWindowAndDisplay(token,
- const_cast<const std::unordered_map<ui::LogicalDisplayId,
- TouchState>&>(
- touchStatesByDisplay));
-
- return std::make_tuple(const_cast<TouchState*>(constTouchState),
- const_cast<TouchedWindow*>(constTouchedWindow), displayId);
-}
-
bool InputDispatcher::transferTouchGesture(const sp<IBinder>& fromToken, const sp<IBinder>& toToken,
bool isDragDrop) {
if (fromToken == toToken) {
- if (DEBUG_FOCUS) {
- ALOGD("Trivial transfer to same window.");
- }
+ LOG_IF(DEBUG, DEBUG_FOCUS) << "Trivial transfer to same window.";
return true;
}
{ // acquire lock
std::scoped_lock _l(mLock);
- // Find the target touch state and touched window by fromToken.
- auto [state, touchedWindow, displayId] =
- findTouchStateWindowAndDisplay(fromToken, mTouchStates.mTouchStatesByDisplay);
+ ScopedSyntheticEventTracer traceContext(mTracer);
+ CancelationOptions options(CancelationOptions::Mode::CANCEL_POINTER_EVENTS,
+ "transferring touch from this window to another window",
+ traceContext.getTracker());
- if (state == nullptr || touchedWindow == nullptr) {
- ALOGD("Touch transfer failed because from window is not being touched.");
- return false;
- }
- std::set<DeviceId> deviceIds = touchedWindow->getTouchingDeviceIds();
- if (deviceIds.size() != 1) {
- LOG(INFO) << "Can't transfer touch. Currently touching devices: "
- << dumpContainer(deviceIds) << " for window: " << touchedWindow->dump();
- return false;
- }
- const DeviceId deviceId = *deviceIds.begin();
-
- const sp<WindowInfoHandle> fromWindowHandle = touchedWindow->windowHandle;
- const sp<WindowInfoHandle> toWindowHandle =
- mWindowInfos.findWindowHandle(toToken, displayId);
- if (!toWindowHandle) {
- ALOGW("Cannot transfer touch because the transfer target window was not found.");
+ auto result = mTouchStates.transferTouchGesture(fromToken, toToken, mWindowInfos,
+ mConnectionManager);
+ if (!result.has_value()) {
return false;
}
- if (DEBUG_FOCUS) {
- ALOGD("%s: fromWindowHandle=%s, toWindowHandle=%s", __func__,
- touchedWindow->windowHandle->getName().c_str(),
- toWindowHandle->getName().c_str());
+ const auto& [toWindowHandle, deviceId, pointers, cancellations, pointerDowns] =
+ result.value();
+
+ for (const auto& cancellationArgs : cancellations) {
+ LOG_ALWAYS_FATAL_IF(cancellationArgs.mode !=
+ CancelationOptions::Mode::CANCEL_POINTER_EVENTS);
+ LOG_ALWAYS_FATAL_IF(cancellationArgs.deviceId.has_value());
+ synthesizeCancelationEventsForWindowLocked(cancellationArgs.windowHandle, options);
}
- // Erase old window.
- ftl::Flags<InputTarget::Flags> oldTargetFlags = touchedWindow->targetFlags;
- std::vector<PointerProperties> pointers = touchedWindow->getTouchingPointers(deviceId);
- state->removeWindowByToken(fromToken);
-
- // Add new window.
- nsecs_t downTimeInTarget = now();
- ftl::Flags<InputTarget::Flags> newTargetFlags =
- oldTargetFlags & (InputTarget::Flags::SPLIT);
- if (canReceiveForegroundTouches(*toWindowHandle->getInfo())) {
- newTargetFlags |= InputTarget::Flags::FOREGROUND;
+ for (const auto& pointerDownArgs : pointerDowns) {
+ synthesizePointerDownEventsForConnectionLocked(pointerDownArgs.downTimeInTarget,
+ pointerDownArgs.connection,
+ pointerDownArgs.targetFlags,
+ traceContext.getTracker());
}
- // Transferring touch focus using this API should not effect the focused window.
- newTargetFlags |= InputTarget::Flags::NO_FOCUS_CHANGE;
- state->addOrUpdateWindow(toWindowHandle, InputTarget::DispatchMode::AS_IS, newTargetFlags,
- deviceId, pointers, downTimeInTarget);
// Store the dragging window.
if (isDragDrop) {
@@ -5896,30 +5778,6 @@
const size_t id = pointers.begin()->id;
mDragState = std::make_unique<DragState>(toWindowHandle, deviceId, id);
}
-
- // Synthesize cancel for old window and down for new window.
- ScopedSyntheticEventTracer traceContext(mTracer);
- std::shared_ptr<Connection> fromConnection = mConnectionManager.getConnection(fromToken);
- std::shared_ptr<Connection> toConnection = mConnectionManager.getConnection(toToken);
- if (fromConnection != nullptr && toConnection != nullptr) {
- fromConnection->inputState.mergePointerStateTo(toConnection->inputState);
- CancelationOptions options(CancelationOptions::Mode::CANCEL_POINTER_EVENTS,
- "transferring touch from this window to another window",
- traceContext.getTracker());
- synthesizeCancelationEventsForWindowLocked(fromWindowHandle, options, fromConnection);
-
- // Check if the wallpaper window should deliver the corresponding event.
- transferWallpaperTouch(oldTargetFlags, newTargetFlags, fromWindowHandle, toWindowHandle,
- *state, deviceId, pointers, traceContext.getTracker());
-
- // Because new window may have a wallpaper window, it will merge input state from it
- // parent window, after this the firstNewPointerIdx in input state will be reset, then
- // it will cause new move event be thought inconsistent, so we should synthesize the
- // down event after it reset.
- synthesizePointerDownEventsForConnectionLocked(downTimeInTarget, toConnection,
- newTargetFlags,
- traceContext.getTracker());
- }
} // release lock
// Wake up poll loop since it may need to make new input dispatching choices.
@@ -5927,6 +5785,83 @@
return true;
}
+std::optional<std::tuple<sp<gui::WindowInfoHandle>, DeviceId, std::vector<PointerProperties>,
+ std::list<InputDispatcher::DispatcherTouchState::CancellationArgs>,
+ std::list<InputDispatcher::DispatcherTouchState::PointerDownArgs>>>
+InputDispatcher::DispatcherTouchState::transferTouchGesture(const sp<android::IBinder>& fromToken,
+ const sp<android::IBinder>& toToken,
+ const DispatcherWindowInfo& windowInfos,
+ const ConnectionManager& connections) {
+ // Find the target touch state and touched window by fromToken.
+ auto touchStateWindowAndDisplay = findTouchStateWindowAndDisplay(fromToken);
+ if (!touchStateWindowAndDisplay.has_value()) {
+ ALOGD("Touch transfer failed because from window is not being touched.");
+ return std::nullopt;
+ }
+
+ auto [state, touchedWindow, displayId] = touchStateWindowAndDisplay.value();
+ std::set<DeviceId> deviceIds = touchedWindow.getTouchingDeviceIds();
+ if (deviceIds.size() != 1) {
+ LOG(INFO) << "Can't transfer touch. Currently touching devices: "
+ << dumpContainer(deviceIds) << " for window: " << touchedWindow.dump();
+ return std::nullopt;
+ }
+ const DeviceId deviceId = *deviceIds.begin();
+
+ const sp<WindowInfoHandle> fromWindowHandle = touchedWindow.windowHandle;
+ const sp<WindowInfoHandle> toWindowHandle = windowInfos.findWindowHandle(toToken, displayId);
+ if (!toWindowHandle) {
+ ALOGW("Cannot transfer touch because the transfer target window was not found.");
+ return std::nullopt;
+ }
+
+ LOG_IF(DEBUG, DEBUG_FOCUS) << __func__ << ": fromWindowHandle=" << fromWindowHandle->getName()
+ << ", toWindowHandle=" << toWindowHandle->getName();
+
+ // Erase old window.
+ ftl::Flags<InputTarget::Flags> oldTargetFlags = touchedWindow.targetFlags;
+ std::vector<PointerProperties> pointers = touchedWindow.getTouchingPointers(deviceId);
+ state.removeWindowByToken(fromToken);
+
+ // Add new window.
+ nsecs_t downTimeInTarget = now();
+ ftl::Flags<InputTarget::Flags> newTargetFlags = oldTargetFlags & (InputTarget::Flags::SPLIT);
+ if (canReceiveForegroundTouches(*toWindowHandle->getInfo())) {
+ newTargetFlags |= InputTarget::Flags::FOREGROUND;
+ }
+ // Transferring touch focus using this API should not effect the focused window.
+ newTargetFlags |= InputTarget::Flags::NO_FOCUS_CHANGE;
+ state.addOrUpdateWindow(toWindowHandle, InputTarget::DispatchMode::AS_IS, newTargetFlags,
+ deviceId, pointers, downTimeInTarget);
+
+ // Synthesize cancel for old window and down for new window.
+ std::shared_ptr<Connection> fromConnection = connections.getConnection(fromToken);
+ std::shared_ptr<Connection> toConnection = connections.getConnection(toToken);
+ std::list<CancellationArgs> cancellations;
+ std::list<PointerDownArgs> pointerDowns;
+ if (fromConnection != nullptr && toConnection != nullptr) {
+ fromConnection->inputState.mergePointerStateTo(toConnection->inputState);
+ cancellations.emplace_back(fromWindowHandle,
+ CancelationOptions::Mode::CANCEL_POINTER_EVENTS);
+
+ // Check if the wallpaper window should deliver the corresponding event.
+ auto [wallpaperCancellations, wallpaperPointerDowns] =
+ transferWallpaperTouch(fromWindowHandle, toWindowHandle, state, deviceId, pointers,
+ oldTargetFlags, newTargetFlags, windowInfos, connections);
+
+ cancellations.splice(cancellations.end(), wallpaperCancellations);
+ pointerDowns.splice(pointerDowns.end(), wallpaperPointerDowns);
+
+ // Because new window may have a wallpaper window, it will merge input state from it
+ // parent window, after this the firstNewPointerIdx in input state will be reset, then
+ // it will cause new move event be thought inconsistent, so we should synthesize the
+ // down event after it reset.
+ pointerDowns.emplace_back(downTimeInTarget, toConnection, newTargetFlags);
+ }
+
+ return std::make_tuple(toWindowHandle, deviceId, pointers, cancellations, pointerDowns);
+}
+
/**
* Get the touched foreground window on the given display.
* Return null if there are no windows touched on that display, or if more than one foreground
@@ -5984,9 +5919,7 @@
}
void InputDispatcher::resetAndDropEverythingLocked(const char* reason) {
- if (DEBUG_FOCUS) {
- ALOGD("Resetting and dropping all events (%s).", reason);
- }
+ LOG_IF(DEBUG, DEBUG_FOCUS) << "Resetting and dropping all events (" << reason << ").";
ScopedSyntheticEventTracer traceContext(mTracer);
CancelationOptions options(CancelationOptions::Mode::CANCEL_ALL_EVENTS, reason,
@@ -6141,9 +6074,7 @@
};
Result<std::unique_ptr<InputChannel>> InputDispatcher::createInputChannel(const std::string& name) {
- if (DEBUG_CHANNEL_CREATION) {
- ALOGD("channel '%s' ~ createInputChannel", name.c_str());
- }
+ LOG_IF(DEBUG, DEBUG_CHANNEL_CREATION) << "channel '" << name << "' ~ createInputChannel";
std::unique_ptr<InputChannel> serverChannel;
std::unique_ptr<InputChannel> clientChannel;
@@ -6259,43 +6190,62 @@
return BAD_VALUE;
}
- auto [statePtr, windowPtr, displayId] =
- findTouchStateWindowAndDisplay(token, mTouchStates.mTouchStatesByDisplay);
- if (statePtr == nullptr || windowPtr == nullptr) {
- LOG(WARNING)
- << "Attempted to pilfer points from a channel without any on-going pointer streams."
- " Ignoring.";
- return BAD_VALUE;
- }
- std::set<int32_t> deviceIds = windowPtr->getTouchingDeviceIds();
- if (deviceIds.empty()) {
- LOG(WARNING) << "Can't pilfer: no touching devices in window: " << windowPtr->dump();
- return BAD_VALUE;
+ const auto result = mTouchStates.pilferPointers(token, *requestingConnection);
+ if (!result.ok()) {
+ return result.error().code();
}
ScopedSyntheticEventTracer traceContext(mTracer);
+ CancelationOptions options(CancelationOptions::Mode::CANCEL_POINTER_EVENTS,
+ "input channel stole pointer stream", traceContext.getTracker());
+ const auto cancellations = *result;
+ for (const auto& cancellationArgs : cancellations) {
+ LOG_ALWAYS_FATAL_IF(cancellationArgs.mode !=
+ CancelationOptions::Mode::CANCEL_POINTER_EVENTS);
+ options.displayId = cancellationArgs.displayId;
+ options.deviceId = cancellationArgs.deviceId;
+ options.pointerIds = cancellationArgs.pointerIds;
+ synthesizeCancelationEventsForWindowLocked(cancellationArgs.windowHandle, options);
+ }
+ return OK;
+}
+
+base::Result<std::list<InputDispatcher::DispatcherTouchState::CancellationArgs>, status_t>
+InputDispatcher::DispatcherTouchState::pilferPointers(const sp<IBinder>& token,
+ const Connection& requestingConnection) {
+ auto touchStateWindowAndDisplay = findTouchStateWindowAndDisplay(token);
+ if (!touchStateWindowAndDisplay.has_value()) {
+ LOG(WARNING)
+ << "Attempted to pilfer points from a channel without any on-going pointer streams."
+ " Ignoring.";
+ return Error(BAD_VALUE);
+ }
+
+ auto [state, window, displayId] = touchStateWindowAndDisplay.value();
+
+ std::set<int32_t> deviceIds = window.getTouchingDeviceIds();
+ if (deviceIds.empty()) {
+ LOG(WARNING) << "Can't pilfer: no touching devices in window: " << window.dump();
+ return Error(BAD_VALUE);
+ }
+
+ std::list<CancellationArgs> cancellations;
for (const DeviceId deviceId : deviceIds) {
- TouchState& state = *statePtr;
- TouchedWindow& window = *windowPtr;
// Send cancel events to all the input channels we're stealing from.
- CancelationOptions options(CancelationOptions::Mode::CANCEL_POINTER_EVENTS,
- "input channel stole pointer stream", traceContext.getTracker());
- options.deviceId = deviceId;
- options.displayId = displayId;
std::vector<PointerProperties> pointers = window.getTouchingPointers(deviceId);
std::bitset<MAX_POINTER_ID + 1> pointerIds = getPointerIds(pointers);
- options.pointerIds = pointerIds;
-
std::string canceledWindows;
for (const TouchedWindow& w : state.windows) {
if (w.windowHandle->getToken() != token) {
- synthesizeCancelationEventsForWindowLocked(w.windowHandle, options);
+ cancellations.emplace_back(w.windowHandle,
+ CancelationOptions::Mode::CANCEL_POINTER_EVENTS,
+ deviceId, displayId, pointerIds);
canceledWindows += canceledWindows.empty() ? "[" : ", ";
canceledWindows += w.windowHandle->getName();
}
}
canceledWindows += canceledWindows.empty() ? "[]" : "]";
- LOG(INFO) << "Channel " << requestingConnection->getInputChannelName()
+ LOG(INFO) << "Channel " << requestingConnection.getInputChannelName()
<< " is stealing input gesture for device " << deviceId << " from "
<< canceledWindows;
@@ -6305,7 +6255,7 @@
state.cancelPointersForWindowsExcept(deviceId, pointerIds, token);
}
- return OK;
+ return cancellations;
}
void InputDispatcher::requestPointerCapture(const sp<IBinder>& windowToken, bool enabled) {
@@ -6675,12 +6625,11 @@
// then cancel the associated fallback key, if any.
if (fallbackKeyCode) {
// Dispatch the unhandled key to the policy with the cancel flag.
- if (DEBUG_OUTBOUND_EVENT_DETAILS) {
- ALOGD("Unhandled key event: Asking policy to cancel fallback action. "
- "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
- keyEntry.keyCode, keyEntry.action, keyEntry.repeatCount,
- keyEntry.policyFlags);
- }
+ LOG_IF(DEBUG, DEBUG_OUTBOUND_EVENT_DETAILS)
+ << "Unhandled key event: Asking policy to cancel fallback action. keyCode="
+ << keyEntry.keyCode << ", action=" << keyEntry.action
+ << ", repeatCount=" << keyEntry.repeatCount << ", policyFlags=0x" << std::hex
+ << keyEntry.policyFlags;
KeyEvent event = createKeyEvent(keyEntry);
event.setFlags(event.getFlags() | AKEY_EVENT_FLAG_CANCELED);
@@ -6717,21 +6666,22 @@
// Then ask the policy what to do with it.
bool initialDown = keyEntry.action == AKEY_EVENT_ACTION_DOWN && keyEntry.repeatCount == 0;
if (!fallbackKeyCode && !initialDown) {
- if (DEBUG_OUTBOUND_EVENT_DETAILS) {
- ALOGD("Unhandled key event: Skipping unhandled key event processing "
- "since this is not an initial down. "
- "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
- originalKeyCode, keyEntry.action, keyEntry.repeatCount, keyEntry.policyFlags);
- }
+ LOG_IF(DEBUG, DEBUG_OUTBOUND_EVENT_DETAILS)
+ << "Unhandled key event: Skipping unhandled key event processing since this is "
+ "not an initial down. keyCode="
+ << originalKeyCode << ", action=" << keyEntry.action
+ << ", repeatCount=" << keyEntry.repeatCount << ", policyFlags=0x" << std::hex
+ << keyEntry.policyFlags;
return {};
}
// Dispatch the unhandled key to the policy.
- if (DEBUG_OUTBOUND_EVENT_DETAILS) {
- ALOGD("Unhandled key event: Asking policy to perform fallback action. "
- "keyCode=%d, action=%d, repeatCount=%d, policyFlags=0x%08x",
- keyEntry.keyCode, keyEntry.action, keyEntry.repeatCount, keyEntry.policyFlags);
- }
+ LOG_IF(DEBUG, DEBUG_OUTBOUND_EVENT_DETAILS)
+ << "Unhandled key event: Asking policy to perform fallback action. keyCode="
+ << keyEntry.keyCode << ", action=" << keyEntry.action
+ << ", repeatCount=" << keyEntry.repeatCount << ", policyFlags=0x" << std::hex
+ << keyEntry.policyFlags;
+ ;
KeyEvent event = createKeyEvent(keyEntry);
mLock.unlock();
@@ -6828,16 +6778,13 @@
newEntry->traceTracker =
mTracer->traceDerivedEvent(*newEntry, *keyEntry.traceTracker);
}
- if (DEBUG_OUTBOUND_EVENT_DETAILS) {
- ALOGD("Unhandled key event: Dispatching fallback key. "
- "originalKeyCode=%d, fallbackKeyCode=%d, fallbackMetaState=%08x",
- originalKeyCode, *fallbackKeyCode, keyEntry.metaState);
- }
+ LOG_IF(DEBUG, DEBUG_OUTBOUND_EVENT_DETAILS)
+ << "Unhandled key event: Dispatching fallback key. originalKeyCode="
+ << originalKeyCode << ", fallbackKeyCode=" << *fallbackKeyCode
+ << ", fallbackMetaState=0x" << std::hex << keyEntry.metaState;
return newEntry;
} else {
- if (DEBUG_OUTBOUND_EVENT_DETAILS) {
- ALOGD("Unhandled key event: No fallback key.");
- }
+ LOG_IF(DEBUG, DEBUG_OUTBOUND_EVENT_DETAILS) << "Unhandled key event: No fallback key.";
// Report the key as unhandled, since there is no fallback key.
mReporter->reportUnhandledKey(keyEntry.id);
@@ -6978,7 +6925,7 @@
return;
}
- ALOGD_IF(DEBUG_FOCUS, "Disabling Pointer Capture because the window lost focus.");
+ LOG_IF(DEBUG, DEBUG_FOCUS) << "Disabling Pointer Capture because the window lost focus.";
if (mCurrentPointerCaptureRequest.isEnable()) {
setPointerCaptureLocked(nullptr);
@@ -7158,12 +7105,15 @@
}
}
-void InputDispatcher::transferWallpaperTouch(
+std::pair<std::list<InputDispatcher::DispatcherTouchState::CancellationArgs>,
+ std::list<InputDispatcher::DispatcherTouchState::PointerDownArgs>>
+InputDispatcher::DispatcherTouchState::transferWallpaperTouch(
+ const sp<gui::WindowInfoHandle> fromWindowHandle,
+ const sp<gui::WindowInfoHandle> toWindowHandle, TouchState& state,
+ android::DeviceId deviceId, const std::vector<PointerProperties>& pointers,
ftl::Flags<InputTarget::Flags> oldTargetFlags,
- ftl::Flags<InputTarget::Flags> newTargetFlags, const sp<WindowInfoHandle> fromWindowHandle,
- const sp<WindowInfoHandle> toWindowHandle, TouchState& state, DeviceId deviceId,
- const std::vector<PointerProperties>& pointers,
- const std::unique_ptr<trace::EventTrackerInterface>& traceTracker) {
+ ftl::Flags<InputTarget::Flags> newTargetFlags, const DispatcherWindowInfo& windowInfos,
+ const ConnectionManager& connections) {
const bool oldHasWallpaper = oldTargetFlags.test(InputTarget::Flags::FOREGROUND) &&
fromWindowHandle->getInfo()->inputConfig.test(
gui::WindowInfo::InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER);
@@ -7174,16 +7124,16 @@
const sp<WindowInfoHandle> oldWallpaper =
oldHasWallpaper ? state.getWallpaperWindow(deviceId) : nullptr;
const sp<WindowInfoHandle> newWallpaper =
- newHasWallpaper ? mWindowInfos.findWallpaperWindowBelow(toWindowHandle) : nullptr;
+ newHasWallpaper ? windowInfos.findWallpaperWindowBelow(toWindowHandle) : nullptr;
if (oldWallpaper == newWallpaper) {
- return;
+ return {};
}
+ std::list<CancellationArgs> cancellations;
+ std::list<PointerDownArgs> pointerDowns;
if (oldWallpaper != nullptr) {
- CancelationOptions options(CancelationOptions::Mode::CANCEL_POINTER_EVENTS,
- "transferring touch focus to another window", traceTracker);
state.removeWindowByToken(oldWallpaper->getToken());
- synthesizeCancelationEventsForWindowLocked(oldWallpaper, options);
+ cancellations.emplace_back(oldWallpaper, CancelationOptions::Mode::CANCEL_POINTER_EVENTS);
}
if (newWallpaper != nullptr) {
@@ -7195,15 +7145,16 @@
state.addOrUpdateWindow(newWallpaper, InputTarget::DispatchMode::AS_IS, wallpaperFlags,
deviceId, pointers, downTimeInTarget);
std::shared_ptr<Connection> wallpaperConnection =
- mConnectionManager.getConnection(newWallpaper->getToken());
+ connections.getConnection(newWallpaper->getToken());
if (wallpaperConnection != nullptr) {
std::shared_ptr<Connection> toConnection =
- mConnectionManager.getConnection(toWindowHandle->getToken());
+ connections.getConnection(toWindowHandle->getToken());
toConnection->inputState.mergePointerStateTo(wallpaperConnection->inputState);
- synthesizePointerDownEventsForConnectionLocked(downTimeInTarget, wallpaperConnection,
- wallpaperFlags, traceTracker);
+ pointerDowns.emplace_back(downTimeInTarget, wallpaperConnection, wallpaperFlags);
}
+ pointerDowns.emplace_back(downTimeInTarget, wallpaperConnection, wallpaperFlags);
}
+ return {cancellations, pointerDowns};
}
sp<WindowInfoHandle> InputDispatcher::DispatcherWindowInfo::findWallpaperWindowBelow(
@@ -7251,6 +7202,12 @@
}
}
+void InputDispatcher::setDisplayTopology(
+ const android::DisplayTopologyGraph& displayTopologyGraph) {
+ std::scoped_lock _l(mLock);
+ mWindowInfos.setDisplayTopology(displayTopologyGraph);
+}
+
InputDispatcher::ConnectionManager::ConnectionManager(const sp<android::Looper>& looper)
: mLooper(looper) {}
@@ -7386,6 +7343,11 @@
mMaximumObscuringOpacityForTouch = opacity;
}
+void InputDispatcher::DispatcherWindowInfo::setDisplayTopology(
+ const DisplayTopologyGraph& displayTopologyGraph) {
+ mTopology = displayTopologyGraph;
+}
+
ftl::Flags<InputTarget::Flags> InputDispatcher::DispatcherTouchState::getTargetFlags(
const sp<WindowInfoHandle>& targetWindow, vec2 targetPosition, bool isSplit,
const DispatcherWindowInfo& windowInfos) {
@@ -7433,6 +7395,40 @@
return false;
}
+std::optional<std::tuple<const sp<gui::WindowInfoHandle>&, ui::LogicalDisplayId>>
+InputDispatcher::DispatcherTouchState::findTouchedWindowHandleAndDisplay(
+ const sp<android::IBinder>& token) const {
+ for (const auto& [displayId, state] : mTouchStatesByDisplay) {
+ for (const TouchedWindow& w : state.windows) {
+ if (w.windowHandle->getToken() == token) {
+ return std::make_tuple(std::ref(w.windowHandle), displayId);
+ }
+ }
+ }
+ return std::nullopt;
+}
+
+void InputDispatcher::DispatcherTouchState::forAllTouchedWindows(
+ std::function<void(const sp<gui::WindowInfoHandle>&)> f) const {
+ for (const auto& [_, state] : mTouchStatesByDisplay) {
+ for (const TouchedWindow& window : state.windows) {
+ f(window.windowHandle);
+ }
+ }
+}
+
+void InputDispatcher::DispatcherTouchState::forAllTouchedWindowsOnDisplay(
+ ui::LogicalDisplayId displayId,
+ std::function<void(const sp<gui::WindowInfoHandle>&)> f) const {
+ const auto touchStateIt = mTouchStatesByDisplay.find(displayId);
+ if (touchStateIt == mTouchStatesByDisplay.end()) {
+ return;
+ }
+ for (const TouchedWindow& window : touchStateIt->second.windows) {
+ f(window.windowHandle);
+ }
+}
+
std::string InputDispatcher::DispatcherTouchState::dump() const {
std::string dump;
if (!mTouchStatesByDisplay.empty()) {
@@ -7457,4 +7453,27 @@
mTouchStatesByDisplay.clear();
}
+std::optional<std::tuple<TouchState&, TouchedWindow&, ui::LogicalDisplayId>>
+InputDispatcher::DispatcherTouchState::findTouchStateWindowAndDisplay(
+ const sp<android::IBinder>& token) {
+ for (auto& [displayId, state] : mTouchStatesByDisplay) {
+ for (TouchedWindow& w : state.windows) {
+ if (w.windowHandle->getToken() == token) {
+ return std::make_tuple(std::ref(state), std::ref(w), displayId);
+ }
+ }
+ }
+ return std::nullopt;
+}
+
+bool InputDispatcher::DispatcherTouchState::isStylusActiveInDisplay(
+ ui::LogicalDisplayId displayId) const {
+ const auto it = mTouchStatesByDisplay.find(displayId);
+ if (it == mTouchStatesByDisplay.end()) {
+ return false;
+ }
+ const TouchState& state = it->second;
+ return state.hasActiveStylus();
+}
+
} // namespace android::inputdispatcher
diff --git a/services/inputflinger/dispatcher/InputDispatcher.h b/services/inputflinger/dispatcher/InputDispatcher.h
index f590806..e76bd89 100644
--- a/services/inputflinger/dispatcher/InputDispatcher.h
+++ b/services/inputflinger/dispatcher/InputDispatcher.h
@@ -164,6 +164,8 @@
void setInputMethodConnectionIsActive(bool isActive) override;
+ void setDisplayTopology(const DisplayTopologyGraph& displayTopologyGraph) override;
+
private:
enum class DropReason {
NOT_DROPPED,
@@ -291,6 +293,8 @@
void setMaximumObscuringOpacityForTouch(float opacity);
+ void setDisplayTopology(const DisplayTopologyGraph& displayTopologyGraph);
+
// Get a reference to window handles by display, return an empty vector if not found.
const std::vector<sp<android::gui::WindowInfoHandle>>& getWindowHandlesForDisplay(
ui::LogicalDisplayId displayId) const;
@@ -319,11 +323,6 @@
ui::LogicalDisplayId displayId, float x, float y, bool isStylus = false,
const sp<android::gui::WindowInfoHandle> ignoreWindow = nullptr) const;
- std::vector<sp<android::gui::WindowInfoHandle>> findTouchedSpyWindowsAt(
- ui::LogicalDisplayId displayId, float x, float y, bool isStylus, DeviceId deviceId,
- const std::unordered_map<ui::LogicalDisplayId, TouchState>& touchStatesByDisplay)
- const;
-
TouchOcclusionInfo computeTouchOcclusionInfo(
const sp<android::gui::WindowInfoHandle>& windowHandle, float x, float y) const;
@@ -346,6 +345,11 @@
std::unordered_map<ui::LogicalDisplayId /*displayId*/, android::gui::DisplayInfo>
mDisplayInfos;
float mMaximumObscuringOpacityForTouch{1.0f};
+
+ // Topology is initialized with default-constructed value, which is an empty topology until
+ // we receive setDisplayTopology call. Meanwhile we will treat every display as an
+ // independent display.
+ DisplayTopologyGraph mTopology;
};
DispatcherWindowInfo mWindowInfos GUARDED_BY(mLock);
@@ -355,7 +359,15 @@
struct CancellationArgs {
const sp<gui::WindowInfoHandle> windowHandle;
CancelationOptions::Mode mode;
- std::optional<DeviceId> deviceId;
+ std::optional<DeviceId> deviceId{std::nullopt};
+ ui::LogicalDisplayId displayId{ui::LogicalDisplayId::INVALID};
+ std::bitset<MAX_POINTER_ID + 1> pointerIds{};
+ };
+
+ struct PointerDownArgs {
+ const nsecs_t downTimeInTarget;
+ const std::shared_ptr<Connection> connection;
+ const ftl::Flags<InputTarget::Flags> targetFlags;
};
static void addPointerWindowTarget(const sp<android::gui::WindowInfoHandle>& windowHandle,
@@ -384,20 +396,62 @@
bool isPointerInWindow(const sp<android::IBinder>& token, ui::LogicalDisplayId displayId,
DeviceId deviceId, int32_t pointerId) const;
+ // Find touched windowHandle and display by token.
+ std::optional<std::tuple<const sp<gui::WindowInfoHandle>&, ui::LogicalDisplayId>>
+ findTouchedWindowHandleAndDisplay(const sp<IBinder>& token) const;
+
+ void forAllTouchedWindows(std::function<void(const sp<gui::WindowInfoHandle>&)> f) const;
+
+ void forAllTouchedWindowsOnDisplay(
+ ui::LogicalDisplayId displayId,
+ std::function<void(const sp<gui::WindowInfoHandle>&)> f) const;
+
std::string dump() const;
// Updates the touchState for display from WindowInfo,
- // return vector of CancellationArgs for every cancelled touch
+ // returns list of CancellationArgs for every cancelled touch
std::list<CancellationArgs> updateFromWindowInfo(ui::LogicalDisplayId displayId,
const DispatcherWindowInfo& windowInfos);
void removeAllPointersForDevice(DeviceId deviceId);
+ // transfer touch between provided tokens, returns destination WindowHandle, deviceId,
+ // pointers, list of cancelled windows and pointers on successful transfer.
+ std::optional<
+ std::tuple<sp<gui::WindowInfoHandle>, DeviceId, std::vector<PointerProperties>,
+ std::list<CancellationArgs>, std::list<PointerDownArgs>>>
+ transferTouchGesture(const sp<IBinder>& fromToken, const sp<IBinder>& toToken,
+ const DispatcherWindowInfo& windowInfos,
+ const ConnectionManager& connections);
+
+ base::Result<std::list<CancellationArgs>, status_t> pilferPointers(
+ const sp<IBinder>& token, const Connection& requestingConnection);
+
void clear();
+ private:
std::unordered_map<ui::LogicalDisplayId, TouchState> mTouchStatesByDisplay;
- private:
+ std::optional<std::tuple<TouchState&, TouchedWindow&, ui::LogicalDisplayId>>
+ findTouchStateWindowAndDisplay(const sp<IBinder>& token);
+
+ std::pair<std::list<CancellationArgs>, std::list<PointerDownArgs>> transferWallpaperTouch(
+ const sp<gui::WindowInfoHandle> fromWindowHandle,
+ const sp<gui::WindowInfoHandle> toWindowHandle, TouchState& state,
+ DeviceId deviceId, const std::vector<PointerProperties>& pointers,
+ ftl::Flags<InputTarget::Flags> oldTargetFlags,
+ ftl::Flags<InputTarget::Flags> newTargetFlags,
+ const DispatcherWindowInfo& windowInfos, const ConnectionManager& connections);
+
+ bool canWindowReceiveMotion(const sp<android::gui::WindowInfoHandle>& window,
+ const MotionEntry& motionEntry,
+ const ConnectionManager& connections,
+ const DispatcherWindowInfo& windowInfos) const;
+
+ // Return true if stylus is currently down anywhere on the specified display,
+ // and false otherwise.
+ bool isStylusActiveInDisplay(ui::LogicalDisplayId displayId) const;
+
static std::list<CancellationArgs> eraseRemovedWindowsFromWindowInfo(
TouchState& state, ui::LogicalDisplayId displayId,
const DispatcherWindowInfo& windowInfos);
@@ -553,11 +607,6 @@
sp<android::gui::WindowInfoHandle> getFocusedWindowHandleLocked(
ui::LogicalDisplayId displayId) const REQUIRES(mLock);
- static bool canWindowReceiveMotion(
- const sp<android::gui::WindowInfoHandle>& window, const MotionEntry& motionEntry,
- const ConnectionManager& connections, const DispatcherWindowInfo& windowInfos,
- const std::unordered_map<ui::LogicalDisplayId, TouchState>& touchStates);
-
// Returns all the input targets (with their respective input channels) from the window handles
// passed as argument.
std::vector<InputTarget> getInputTargetsFromWindowHandlesLocked(
@@ -727,6 +776,10 @@
std::string getApplicationWindowLabel(const InputApplicationHandle* applicationHandle,
const sp<android::gui::WindowInfoHandle>& windowHandle);
+ static std::vector<sp<android::gui::WindowInfoHandle>> findTouchedSpyWindowsAt(
+ ui::LogicalDisplayId displayId, float x, float y, bool isStylus, DeviceId deviceId,
+ const DispatcherWindowInfo& windowInfos);
+
static bool shouldDropInput(const EventEntry& entry,
const sp<android::gui::WindowInfoHandle>& windowHandle,
const DispatcherWindowInfo& windowInfo);
@@ -824,17 +877,6 @@
const std::shared_ptr<Connection>& connection, DispatchEntry* dispatchEntry,
bool handled) REQUIRES(mLock);
- // Find touched state and touched window by token.
- static std::tuple<TouchState*, TouchedWindow*, ui::LogicalDisplayId>
- findTouchStateWindowAndDisplay(
- const sp<IBinder>& token,
- std::unordered_map<ui::LogicalDisplayId, TouchState>& touchStatesByDisplay);
-
- static std::tuple<const TouchState*, const TouchedWindow*, ui::LogicalDisplayId>
- findTouchStateWindowAndDisplay(
- const sp<IBinder>& token,
- const std::unordered_map<ui::LogicalDisplayId, TouchState>& touchStatesByDisplay);
-
// Statistics gathering.
nsecs_t mLastStatisticPushTime = 0;
std::unique_ptr<InputEventTimelineProcessor> mInputEventTimelineProcessor GUARDED_BY(mLock);
@@ -849,15 +891,6 @@
sp<InputReporterInterface> mReporter;
- void transferWallpaperTouch(ftl::Flags<InputTarget::Flags> oldTargetFlags,
- ftl::Flags<InputTarget::Flags> newTargetFlags,
- const sp<android::gui::WindowInfoHandle> fromWindowHandle,
- const sp<android::gui::WindowInfoHandle> toWindowHandle,
- TouchState& state, DeviceId deviceId,
- const std::vector<PointerProperties>& pointers,
- const std::unique_ptr<trace::EventTrackerInterface>& traceTracker)
- REQUIRES(mLock);
-
/** Stores the value of the input flag for per device input latency metrics. */
const bool mPerDeviceInputLatencyMetricsFlag =
com::android::input::flags::enable_per_device_input_latency_metrics();
diff --git a/services/inputflinger/dispatcher/include/InputDispatcherInterface.h b/services/inputflinger/dispatcher/include/InputDispatcherInterface.h
index 463a952..ab039c3 100644
--- a/services/inputflinger/dispatcher/include/InputDispatcherInterface.h
+++ b/services/inputflinger/dispatcher/include/InputDispatcherInterface.h
@@ -24,6 +24,7 @@
#include <android/os/InputEventInjectionSync.h>
#include <gui/InputApplication.h>
#include <gui/WindowInfo.h>
+#include <input/DisplayTopologyGraph.h>
#include <input/InputDevice.h>
#include <input/InputTransport.h>
#include <unordered_map>
@@ -243,6 +244,11 @@
* Notify the dispatcher that the state of the input method connection changed.
*/
virtual void setInputMethodConnectionIsActive(bool isActive) = 0;
+
+ /*
+ * Notify the dispatcher of the latest DisplayTopology.
+ */
+ virtual void setDisplayTopology(const DisplayTopologyGraph& displayTopologyGraph) = 0;
};
} // namespace android
diff --git a/services/inputflinger/reader/EventHub.cpp b/services/inputflinger/reader/EventHub.cpp
index 013ef86..3c8b6f5 100644
--- a/services/inputflinger/reader/EventHub.cpp
+++ b/services/inputflinger/reader/EventHub.cpp
@@ -1620,41 +1620,43 @@
const auto& path = *sysfsRootPathOpt;
- std::shared_ptr<const AssociatedDevice> associatedDevice = std::make_shared<AssociatedDevice>(
- AssociatedDevice{.sysfsRootPath = path,
- .batteryInfos = readBatteryConfiguration(path),
- .lightInfos = readLightsConfiguration(path),
- .layoutInfo = readLayoutConfiguration(path)});
-
- bool associatedDeviceChanged = false;
+ std::shared_ptr<const AssociatedDevice> associatedDevice;
for (const auto& [id, dev] : mDevices) {
- if (dev->associatedDevice && dev->associatedDevice->sysfsRootPath == path) {
- if (*associatedDevice != *dev->associatedDevice) {
- associatedDeviceChanged = true;
- dev->associatedDevice = associatedDevice;
- }
- associatedDevice = dev->associatedDevice;
+ if (!dev->associatedDevice || dev->associatedDevice->sysfsRootPath != path) {
+ continue;
}
+ if (!associatedDevice) {
+ // Found matching associated device for the first time.
+ associatedDevice = dev->associatedDevice;
+ // Reload this associated device if needed.
+ const auto reloadedDevice = AssociatedDevice(path);
+ if (reloadedDevice != *dev->associatedDevice) {
+ ALOGI("The AssociatedDevice changed for path '%s'. Using new AssociatedDevice: %s",
+ path.c_str(), associatedDevice->dump().c_str());
+ associatedDevice = std::make_shared<AssociatedDevice>(std::move(reloadedDevice));
+ }
+ }
+ // Update the associatedDevice.
+ dev->associatedDevice = associatedDevice;
}
- ALOGI_IF(associatedDeviceChanged,
- "The AssociatedDevice changed for path '%s'. Using new AssociatedDevice: %s",
- path.c_str(), associatedDevice->dump().c_str());
+
+ if (!associatedDevice) {
+ // No existing associated device found for this path, so create a new one.
+ associatedDevice = std::make_shared<AssociatedDevice>(path);
+ }
return associatedDevice;
}
-bool EventHub::AssociatedDevice::isChanged() const {
- std::unordered_map<int32_t, RawBatteryInfo> newBatteryInfos =
- readBatteryConfiguration(sysfsRootPath);
- std::unordered_map<int32_t, RawLightInfo> newLightInfos =
- readLightsConfiguration(sysfsRootPath);
- std::optional<RawLayoutInfo> newLayoutInfo = readLayoutConfiguration(sysfsRootPath);
+EventHub::AssociatedDevice::AssociatedDevice(const std::filesystem::path& sysfsRootPath)
+ : sysfsRootPath(sysfsRootPath),
+ batteryInfos(readBatteryConfiguration(sysfsRootPath)),
+ lightInfos(readLightsConfiguration(sysfsRootPath)),
+ layoutInfo(readLayoutConfiguration(sysfsRootPath)) {}
- if (newBatteryInfos == batteryInfos && newLightInfos == lightInfos &&
- newLayoutInfo == layoutInfo) {
- return false;
- }
- return true;
+std::string EventHub::AssociatedDevice::dump() const {
+ return StringPrintf("path=%s, numBatteries=%zu, numLight=%zu", sysfsRootPath.c_str(),
+ batteryInfos.size(), lightInfos.size());
}
void EventHub::vibrate(int32_t deviceId, const VibrationElement& element) {
@@ -2646,33 +2648,56 @@
void EventHub::sysfsNodeChanged(const std::string& sysfsNodePath) {
std::scoped_lock _l(mLock);
- // Check in opening devices
- for (auto it = mOpeningDevices.begin(); it != mOpeningDevices.end(); it++) {
- std::unique_ptr<Device>& device = *it;
- if (device->associatedDevice &&
- sysfsNodePath.find(device->associatedDevice->sysfsRootPath.string()) !=
- std::string::npos &&
- device->associatedDevice->isChanged()) {
- it = mOpeningDevices.erase(it);
- openDeviceLocked(device->path);
+ // Testing whether a sysfs node changed involves several syscalls, so use a cache to avoid
+ // testing the same node multiple times.
+ std::map<std::shared_ptr<const AssociatedDevice>, bool /*changed*/> testedDevices;
+ auto isAssociatedDeviceChanged = [&testedDevices, &sysfsNodePath](const Device& dev) {
+ if (!dev.associatedDevice) {
+ return false;
+ }
+ if (auto testedIt = testedDevices.find(dev.associatedDevice);
+ testedIt != testedDevices.end()) {
+ return testedIt->second;
+ }
+ // Cache miss
+ if (sysfsNodePath.find(dev.associatedDevice->sysfsRootPath.string()) == std::string::npos) {
+ testedDevices.emplace(dev.associatedDevice, false);
+ return false;
+ }
+ auto reloadedDevice = AssociatedDevice(dev.associatedDevice->sysfsRootPath);
+ const bool changed = *dev.associatedDevice != reloadedDevice;
+ testedDevices.emplace(dev.associatedDevice, changed);
+ return changed;
+ };
+
+ std::set<Device*> devicesToClose;
+ std::set<std::string /*path*/> devicesToOpen;
+
+ // Check in opening devices. If its associated device changed,
+ // the device should be removed from mOpeningDevices and needs to be opened again.
+ std::erase_if(mOpeningDevices, [&](const auto& dev) {
+ if (isAssociatedDeviceChanged(*dev)) {
+ devicesToOpen.emplace(dev->path);
+ return true;
+ }
+ return false;
+ });
+
+ // Check in already added device. If its associated device changed,
+ // the device needs to be re-opened.
+ for (const auto& [id, dev] : mDevices) {
+ if (isAssociatedDeviceChanged(*dev)) {
+ devicesToOpen.emplace(dev->path);
+ devicesToClose.emplace(dev.get());
}
}
- // Check in already added device
- std::vector<Device*> devicesToReopen;
- for (const auto& [id, device] : mDevices) {
- if (device->associatedDevice &&
- sysfsNodePath.find(device->associatedDevice->sysfsRootPath.string()) !=
- std::string::npos &&
- device->associatedDevice->isChanged()) {
- devicesToReopen.push_back(device.get());
- }
- }
- for (const auto& device : devicesToReopen) {
+ for (auto* device : devicesToClose) {
closeDeviceLocked(*device);
- openDeviceLocked(device->path);
}
- devicesToReopen.clear();
+ for (const auto& path : devicesToOpen) {
+ openDeviceLocked(path);
+ }
}
void EventHub::createVirtualKeyboardLocked() {
@@ -2972,9 +2997,4 @@
std::unique_lock<std::mutex> lock(mLock);
}
-std::string EventHub::AssociatedDevice::dump() const {
- return StringPrintf("path=%s, numBatteries=%zu, numLight=%zu", sysfsRootPath.c_str(),
- batteryInfos.size(), lightInfos.size());
-}
-
} // namespace android
diff --git a/services/inputflinger/reader/include/EventHub.h b/services/inputflinger/reader/include/EventHub.h
index 5839b4c..31ac63f 100644
--- a/services/inputflinger/reader/include/EventHub.h
+++ b/services/inputflinger/reader/include/EventHub.h
@@ -619,13 +619,13 @@
private:
// Holds information about the sysfs device associated with the Device.
struct AssociatedDevice {
+ AssociatedDevice(const std::filesystem::path& sysfsRootPath);
// The sysfs root path of the misc device.
std::filesystem::path sysfsRootPath;
std::unordered_map<int32_t /*batteryId*/, RawBatteryInfo> batteryInfos;
std::unordered_map<int32_t /*lightId*/, RawLightInfo> lightInfos;
std::optional<RawLayoutInfo> layoutInfo;
- bool isChanged() const;
bool operator==(const AssociatedDevice&) const = default;
bool operator!=(const AssociatedDevice&) const = default;
std::string dump() const;
diff --git a/services/sensorservice/aidl/fuzzer/Android.bp b/services/sensorservice/aidl/fuzzer/Android.bp
index 880df08..f38cf5a 100644
--- a/services/sensorservice/aidl/fuzzer/Android.bp
+++ b/services/sensorservice/aidl/fuzzer/Android.bp
@@ -22,6 +22,7 @@
"android.hardware.sensors-V1-convert",
"android.hardware.sensors-V3-ndk",
"android.hardware.common-V2-ndk",
+ "framework-permission-aidl-cpp",
"libsensor",
"libfakeservicemanager",
"libcutils",
diff --git a/services/surfaceflinger/Android.bp b/services/surfaceflinger/Android.bp
index ea7d6d7..9aa1ffa 100644
--- a/services/surfaceflinger/Android.bp
+++ b/services/surfaceflinger/Android.bp
@@ -93,7 +93,6 @@
"iinputflinger_aidl_lib_static",
"libaidlcommonsupport",
"libcompositionengine",
- "libframetimeline",
"libgui_aidl_static",
"libperfetto_client_experimental",
"librenderengine",
@@ -206,9 +205,9 @@
"Display/DisplayModeController.cpp",
"Display/DisplaySnapshot.cpp",
"DisplayDevice.cpp",
- "DisplayRenderArea.cpp",
"Effects/Daltonizer.cpp",
"FpsReporter.cpp",
+ "FrameTimeline/FrameTimeline.cpp",
"FrameTracer/FrameTracer.cpp",
"FrameTracker.cpp",
"FrontEnd/LayerCreationArgs.cpp",
@@ -225,12 +224,10 @@
"Layer.cpp",
"LayerFE.cpp",
"LayerProtoHelper.cpp",
- "LayerRenderArea.cpp",
"LayerVector.cpp",
"NativeWindowSurface.cpp",
"RefreshRateOverlay.cpp",
"RegionSamplingThread.cpp",
- "RenderArea.cpp",
"Scheduler/EventThread.cpp",
"Scheduler/FrameRateOverrideMappings.cpp",
"Scheduler/LayerHistory.cpp",
diff --git a/services/surfaceflinger/Client.cpp b/services/surfaceflinger/Client.cpp
index 77bf145..6088e25 100644
--- a/services/surfaceflinger/Client.cpp
+++ b/services/surfaceflinger/Client.cpp
@@ -110,8 +110,8 @@
LayerCreationArgs args(mFlinger.get(), sp<Client>::fromExisting(this),
"MirrorRoot-" + std::to_string(displayId), 0 /* flags */,
gui::LayerMetadata());
- std::optional<DisplayId> id = DisplayId::fromValue(static_cast<uint64_t>(displayId));
- status_t status = mFlinger->mirrorDisplay(*id, args, *outResult);
+ const DisplayId id = DisplayId::fromValue(static_cast<uint64_t>(displayId));
+ status_t status = mFlinger->mirrorDisplay(id, args, *outResult);
return binderStatusFromStatusT(status);
}
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFE.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFE.h
index e876693..780758e 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFE.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/LayerFE.h
@@ -19,6 +19,7 @@
#include <optional>
#include <ostream>
#include <unordered_set>
+#include "aidl/android/hardware/graphics/composer3/Composition.h"
#include "ui/LayerStack.h"
// TODO(b/129481165): remove the #pragma below and fix conversion issues
@@ -36,10 +37,6 @@
#include <utils/RefBase.h>
#include <utils/Timers.h>
-namespace aidl::android::hardware::graphics::composer3 {
-enum class Composition;
-}
-
namespace android {
class Fence;
@@ -182,10 +179,27 @@
// Whether the layer should be rendered with rounded corners.
virtual bool hasRoundedCorners() const = 0;
virtual void setWasClientComposed(const sp<Fence>&) {}
- virtual void setHwcCompositionType(
- aidl::android::hardware::graphics::composer3::Composition) = 0;
- virtual aidl::android::hardware::graphics::composer3::Composition getHwcCompositionType()
- const = 0;
+
+ // These fields are all copied from the last written HWC state.
+ // This state is only used for debugging purposes.
+ struct HwcLayerDebugState {
+ aidl::android::hardware::graphics::composer3::Composition lastCompositionType =
+ aidl::android::hardware::graphics::composer3::Composition::INVALID;
+ // Corresponds to passing an alpha of 0 to HWC2::Layer::setPlaneAlpha.
+ bool wasSkipped = false;
+
+ // Indicates whether the compositionengine::OutputLayer had properties overwritten.
+ // Not directly passed to HWC.
+ bool wasOverridden = false;
+
+ // Corresponds to the GraphicBuffer ID of the buffer passed to HWC2::Layer::setBuffer.
+ // This buffer corresponds to a CachedSet that the LayerFE was flattened to.
+ uint64_t overrideBufferId = 0;
+ };
+
+ // Used for debugging purposes, e.g. perfetto tracing, dumpsys.
+ virtual void setLastHwcState(const LayerFE::HwcLayerDebugState &hwcState) = 0;
+ virtual const HwcLayerDebugState &getLastHwcState() const = 0;
virtual const gui::LayerMetadata* getMetadata() const = 0;
virtual const gui::LayerMetadata* getRelativeMetadata() const = 0;
diff --git a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/LayerFE.h b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/LayerFE.h
index 7744b8b..d2a5a20 100644
--- a/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/LayerFE.h
+++ b/services/surfaceflinger/CompositionEngine/include/compositionengine/mock/LayerFE.h
@@ -59,9 +59,9 @@
MOCK_CONST_METHOD0(getMetadata, gui::LayerMetadata*());
MOCK_CONST_METHOD0(getRelativeMetadata, gui::LayerMetadata*());
MOCK_METHOD0(onPictureProfileCommitted, void());
- MOCK_METHOD(void, setHwcCompositionType,
- (aidl::android::hardware::graphics::composer3::Composition), (override));
- MOCK_METHOD(aidl::android::hardware::graphics::composer3::Composition, getHwcCompositionType,
+ MOCK_METHOD(void, setLastHwcState,
+ (const HwcLayerDebugState&), (override));
+ MOCK_METHOD(const HwcLayerDebugState&, getLastHwcState,
(), (const, override));
};
diff --git a/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp b/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp
index 9b66f01..9d67122 100644
--- a/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/OutputLayer.cpp
@@ -502,6 +502,15 @@
editState().hwc->stateOverridden = isOverridden;
editState().hwc->layerSkipped = skipLayer;
+
+
+ // Save the final HWC state for debugging purposes, e.g. perfetto tracing, dumpsys.
+ getLayerFE().setLastHwcState({.lastCompositionType = editState().hwc->hwcCompositionType,
+ .wasSkipped = skipLayer,
+ .wasOverridden = isOverridden,
+ .overrideBufferId = editState().overrideInfo.buffer
+ ? editState().overrideInfo.buffer.get()->getId()
+ : 0});
}
void OutputLayer::writeOutputDependentGeometryStateToHWC(HWC2::Layer* hwcLayer,
@@ -867,7 +876,6 @@
if (outputDependentState.hwc->hwcCompositionType != requestedCompositionType ||
(outputDependentState.hwc->layerSkipped && !skipLayer)) {
outputDependentState.hwc->hwcCompositionType = requestedCompositionType;
- getLayerFE().setHwcCompositionType(requestedCompositionType);
if (auto error = hwcLayer->setCompositionType(requestedCompositionType);
error != hal::Error::NONE) {
@@ -965,7 +973,13 @@
}
hwcState.hwcCompositionType = compositionType;
- getLayerFE().setHwcCompositionType(compositionType);
+
+ getLayerFE().setLastHwcState({.lastCompositionType = hwcState.hwcCompositionType,
+ .wasSkipped = hwcState.layerSkipped,
+ .wasOverridden = hwcState.stateOverridden,
+ .overrideBufferId = state.overrideInfo.buffer
+ ? state.overrideInfo.buffer.get()->getId()
+ : 0});
}
void OutputLayer::prepareForDeviceLayerRequests() {
diff --git a/services/surfaceflinger/DisplayRenderArea.cpp b/services/surfaceflinger/DisplayRenderArea.cpp
deleted file mode 100644
index c63c738..0000000
--- a/services/surfaceflinger/DisplayRenderArea.cpp
+++ /dev/null
@@ -1,62 +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 "DisplayRenderArea.h"
-#include "DisplayDevice.h"
-
-namespace android {
-
-std::unique_ptr<RenderArea> DisplayRenderArea::create(wp<const DisplayDevice> displayWeak,
- const Rect& sourceCrop, ui::Size reqSize,
- ui::Dataspace reqDataSpace,
- ftl::Flags<Options> options) {
- if (auto display = displayWeak.promote()) {
- // Using new to access a private constructor.
- return std::unique_ptr<DisplayRenderArea>(new DisplayRenderArea(std::move(display),
- sourceCrop, reqSize,
- reqDataSpace, options));
- }
- return nullptr;
-}
-
-DisplayRenderArea::DisplayRenderArea(sp<const DisplayDevice> display, const Rect& sourceCrop,
- ui::Size reqSize, ui::Dataspace reqDataSpace,
- ftl::Flags<Options> options)
- : RenderArea(reqSize, CaptureFill::OPAQUE, reqDataSpace, options),
- mDisplay(std::move(display)),
- mSourceCrop(sourceCrop) {}
-
-const ui::Transform& DisplayRenderArea::getTransform() const {
- return mTransform;
-}
-
-bool DisplayRenderArea::isSecure() const {
- return mOptions.test(Options::CAPTURE_SECURE_LAYERS) && mDisplay->isSecure();
-}
-
-sp<const DisplayDevice> DisplayRenderArea::getDisplayDevice() const {
- return mDisplay;
-}
-
-Rect DisplayRenderArea::getSourceCrop() const {
- // use the projected display viewport by default.
- if (mSourceCrop.isEmpty()) {
- return mDisplay->getLayerStackSpaceRect();
- }
- return mSourceCrop;
-}
-
-} // namespace android
diff --git a/services/surfaceflinger/DisplayRenderArea.h b/services/surfaceflinger/DisplayRenderArea.h
deleted file mode 100644
index 677d019..0000000
--- a/services/surfaceflinger/DisplayRenderArea.h
+++ /dev/null
@@ -1,48 +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.
- */
-
-#pragma once
-
-#include <ui/GraphicTypes.h>
-#include <ui/Transform.h>
-
-#include "RenderArea.h"
-
-namespace android {
-
-class DisplayDevice;
-
-class DisplayRenderArea : public RenderArea {
-public:
- static std::unique_ptr<RenderArea> create(wp<const DisplayDevice>, const Rect& sourceCrop,
- ui::Size reqSize, ui::Dataspace,
- ftl::Flags<Options> options);
-
- const ui::Transform& getTransform() const override;
- bool isSecure() const override;
- sp<const DisplayDevice> getDisplayDevice() const override;
- Rect getSourceCrop() const override;
-
-private:
- DisplayRenderArea(sp<const DisplayDevice>, const Rect& sourceCrop, ui::Size reqSize,
- ui::Dataspace, ftl::Flags<Options> options);
-
- const sp<const DisplayDevice> mDisplay;
- const Rect mSourceCrop;
- const ui::Transform mTransform;
-};
-
-} // namespace android
diff --git a/services/surfaceflinger/FrameTimeline/Android.bp b/services/surfaceflinger/FrameTimeline/Android.bp
deleted file mode 100644
index 8e28cc3..0000000
--- a/services/surfaceflinger/FrameTimeline/Android.bp
+++ /dev/null
@@ -1,35 +0,0 @@
-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"],
- default_team: "trendy_team_android_core_graphics_stack",
-}
-
-cc_library_static {
- name: "libframetimeline",
- defaults: ["surfaceflinger_defaults"],
- srcs: [
- "FrameTimeline.cpp",
- ],
- header_libs: [
- "libscheduler_headers",
- ],
- shared_libs: [
- "android.hardware.graphics.composer@2.4",
- "libbase",
- "libcutils",
- "liblog",
- "libgui",
- "libtimestats",
- "libui",
- "libutils",
- ],
- static_libs: [
- "libperfetto_client_experimental",
- "libsurfaceflinger_common",
- ],
- export_include_dirs: ["."],
-}
diff --git a/services/surfaceflinger/FrontEnd/LayerSnapshot.cpp b/services/surfaceflinger/FrontEnd/LayerSnapshot.cpp
index 523ef7b..839bd79 100644
--- a/services/surfaceflinger/FrontEnd/LayerSnapshot.cpp
+++ b/services/surfaceflinger/FrontEnd/LayerSnapshot.cpp
@@ -403,11 +403,8 @@
if (forceUpdate || requested.what & layer_state_t::eSidebandStreamChanged) {
sidebandStream = requested.sidebandStream;
}
- if (forceUpdate || requested.what & layer_state_t::eShadowRadiusChanged ||
- requested.what & layer_state_t::eClientDrawnShadowsChanged) {
- shadowSettings.length =
- requested.clientDrawnShadowRadius > 0 ? 0.f : requested.shadowRadius;
- shadowSettings.clientDrawnLength = requested.clientDrawnShadowRadius;
+ if (forceUpdate || requested.what & layer_state_t::eShadowRadiusChanged) {
+ shadowSettings.length = requested.shadowRadius;
}
if (forceUpdate || requested.what & layer_state_t::eFrameRateSelectionPriority) {
@@ -537,12 +534,13 @@
}
}
-char LayerSnapshot::classifyCompositionForDebug(Composition compositionType) const {
+char LayerSnapshot::classifyCompositionForDebug(
+ const compositionengine::LayerFE::HwcLayerDebugState& hwcState) const {
if (!isVisible) {
return '.';
}
- switch (compositionType) {
+ switch (hwcState.lastCompositionType) {
case Composition::INVALID:
return 'i';
case Composition::SOLID_COLOR:
@@ -561,21 +559,21 @@
}
char code = '.'; // Default to invisible
- if (hasBufferOrSidebandStream()) {
- code = 'b';
- } else if (fillsColor()) {
- code = 'c'; // Solid color
- } else if (hasBlur()) {
+ if (hasBlur()) {
code = 'l'; // Blur
} else if (hasProtectedContent) {
code = 'p'; // Protected content
- } else if (drawShadows()) {
- code = 's'; // Shadow
} else if (roundedCorner.hasRoundedCorners()) {
code = 'r'; // Rounded corners
+ } else if (drawShadows()) {
+ code = 's'; // Shadow
+ } else if (fillsColor()) {
+ code = 'c'; // Solid color
+ } else if (hasBufferOrSidebandStream()) {
+ code = 'b';
}
- if (compositionType == Composition::CLIENT) {
+ if (hwcState.lastCompositionType == Composition::CLIENT) {
return static_cast<char>(std::toupper(code));
} else {
return code;
diff --git a/services/surfaceflinger/FrontEnd/LayerSnapshot.h b/services/surfaceflinger/FrontEnd/LayerSnapshot.h
index 04b9f3b..69120bd 100644
--- a/services/surfaceflinger/FrontEnd/LayerSnapshot.h
+++ b/services/surfaceflinger/FrontEnd/LayerSnapshot.h
@@ -24,6 +24,7 @@
#include "RequestedLayerState.h"
#include "Scheduler/LayerInfo.h"
#include "android-base/stringprintf.h"
+#include "compositionengine/LayerFE.h"
namespace android::surfaceflinger::frontend {
@@ -163,7 +164,7 @@
// Returns a char summarizing the composition request
// This function tries to maintain parity with planner::Plan chars.
char classifyCompositionForDebug(
- aidl::android::hardware::graphics::composer3::Composition compositionType) const;
+ const compositionengine::LayerFE::HwcLayerDebugState& hwcState) const;
};
} // namespace android::surfaceflinger::frontend
diff --git a/services/surfaceflinger/FrontEnd/RequestedLayerState.cpp b/services/surfaceflinger/FrontEnd/RequestedLayerState.cpp
index 1d53e71..58c235e 100644
--- a/services/surfaceflinger/FrontEnd/RequestedLayerState.cpp
+++ b/services/surfaceflinger/FrontEnd/RequestedLayerState.cpp
@@ -108,7 +108,6 @@
surfaceDamageRegion = Region::INVALID_REGION;
cornerRadius = 0.0f;
clientDrawnCornerRadius = 0.0f;
- clientDrawnShadowRadius = 0.0f;
backgroundBlurRadius = 0;
api = -1;
hasColorTransform = false;
@@ -355,11 +354,6 @@
clientDrawnCornerRadius = clientState.clientDrawnCornerRadius;
changes |= RequestedLayerState::Changes::Geometry;
}
-
- if (clientState.what & layer_state_t::eClientDrawnShadowsChanged) {
- clientDrawnShadowRadius = clientState.clientDrawnShadowRadius;
- changes |= RequestedLayerState::Changes::Geometry;
- }
}
ui::Size RequestedLayerState::getUnrotatedBufferSize(uint32_t displayRotationFlags) const {
@@ -646,7 +640,6 @@
layer_state_t::eColorTransformChanged | layer_state_t::eBackgroundColorChanged |
layer_state_t::eMatrixChanged | layer_state_t::eCornerRadiusChanged |
layer_state_t::eClientDrawnCornerRadiusChanged |
- layer_state_t::eClientDrawnShadowsChanged |
layer_state_t::eBackgroundBlurRadiusChanged | layer_state_t::eBufferTransformChanged |
layer_state_t::eTransformToDisplayInverseChanged | layer_state_t::eCropChanged |
layer_state_t::eDataspaceChanged | layer_state_t::eHdrMetadataChanged |
diff --git a/services/surfaceflinger/Jank/JankTracker.cpp b/services/surfaceflinger/Jank/JankTracker.cpp
index 8e0e084..5e6267d 100644
--- a/services/surfaceflinger/Jank/JankTracker.cpp
+++ b/services/surfaceflinger/Jank/JankTracker.cpp
@@ -88,7 +88,8 @@
}
void JankTracker::addJankListenerLocked(int32_t layerId, sp<IBinder> listener) {
- for (auto it = mJankListeners.find(layerId); it != mJankListeners.end(); it++) {
+ auto range = mJankListeners.equal_range(layerId);
+ for (auto it = range.first; it != range.second; it++) {
if (it->second.mListener == listener) {
// Undo the duplicate increment in addJankListener.
sListenerCount--;
@@ -106,7 +107,8 @@
std::vector<sp<IBinder>> toSend;
mLock.lock();
- for (auto it = mJankListeners.find(layerId); it != mJankListeners.end();) {
+ auto range = mJankListeners.equal_range(layerId);
+ for (auto it = range.first; it != range.second;) {
if (!jankData.empty()) {
toSend.emplace_back(it->second.mListener);
}
@@ -133,7 +135,8 @@
void JankTracker::markJankListenerForRemovalLocked(int32_t layerId, sp<IBinder> listener,
int64_t afterVysnc) {
- for (auto it = mJankListeners.find(layerId); it != mJankListeners.end(); it++) {
+ auto range = mJankListeners.equal_range(layerId);
+ for (auto it = range.first; it != range.second; it++) {
if (it->second.mListener == listener) {
it->second.mRemoveAfter = std::max(static_cast<int64_t>(0), afterVysnc);
return;
@@ -156,7 +159,8 @@
void JankTracker::dropJankListener(int32_t layerId, sp<IBinder> listener) {
const std::lock_guard<std::mutex> _l(mLock);
- for (auto it = mJankListeners.find(layerId); it != mJankListeners.end(); it++) {
+ auto range = mJankListeners.equal_range(layerId);
+ for (auto it = range.first; it != range.second; it++) {
if (it->second.mListener == listener) {
mJankListeners.erase(it);
sListenerCount--;
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 195461f..e1bba44 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -64,7 +64,7 @@
#include "DisplayDevice.h"
#include "DisplayHardware/HWComposer.h"
-#include "FrameTimeline.h"
+#include "FrameTimeline/FrameTimeline.h"
#include "FrameTracer/FrameTracer.h"
#include "FrontEnd/LayerCreationArgs.h"
#include "FrontEnd/LayerHandle.h"
diff --git a/services/surfaceflinger/LayerFE.cpp b/services/surfaceflinger/LayerFE.cpp
index 725a782..b619268 100644
--- a/services/surfaceflinger/LayerFE.cpp
+++ b/services/surfaceflinger/LayerFE.cpp
@@ -428,13 +428,12 @@
return mReleaseFencePromiseStatus;
}
-void LayerFE::setHwcCompositionType(
- aidl::android::hardware::graphics::composer3::Composition type) {
- mLastHwcCompositionType = type;
+void LayerFE::setLastHwcState(const LayerFE::HwcLayerDebugState &state) {
+ mLastHwcState = state;
}
-aidl::android::hardware::graphics::composer3::Composition LayerFE::getHwcCompositionType() const {
- return mLastHwcCompositionType;
-}
+const LayerFE::HwcLayerDebugState& LayerFE::getLastHwcState() const {
+ return mLastHwcState;
+};
} // namespace android
diff --git a/services/surfaceflinger/LayerFE.h b/services/surfaceflinger/LayerFE.h
index 64ec278..a537456 100644
--- a/services/surfaceflinger/LayerFE.h
+++ b/services/surfaceflinger/LayerFE.h
@@ -59,9 +59,10 @@
void setReleaseFence(const FenceResult& releaseFence) override;
LayerFE::ReleaseFencePromiseStatus getReleaseFencePromiseStatus() override;
void onPictureProfileCommitted() override;
- void setHwcCompositionType(aidl::android::hardware::graphics::composer3::Composition) override;
- aidl::android::hardware::graphics::composer3::Composition getHwcCompositionType()
- const override;
+
+ // Used for debugging purposes, e.g. perfetto tracing, dumpsys.
+ void setLastHwcState(const HwcLayerDebugState &state) override;
+ const HwcLayerDebugState &getLastHwcState() const override;
std::unique_ptr<surfaceflinger::frontend::LayerSnapshot> mSnapshot;
@@ -93,8 +94,7 @@
std::string mName;
std::promise<FenceResult> mReleaseFence;
ReleaseFencePromiseStatus mReleaseFencePromiseStatus = ReleaseFencePromiseStatus::UNINITIALIZED;
- aidl::android::hardware::graphics::composer3::Composition mLastHwcCompositionType =
- aidl::android::hardware::graphics::composer3::Composition::INVALID;
+ HwcLayerDebugState mLastHwcState;
};
} // namespace android
diff --git a/services/surfaceflinger/LayerRenderArea.cpp b/services/surfaceflinger/LayerRenderArea.cpp
deleted file mode 100644
index bfe6d2a..0000000
--- a/services/surfaceflinger/LayerRenderArea.cpp
+++ /dev/null
@@ -1,60 +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 <ui/GraphicTypes.h>
-#include <ui/Transform.h>
-
-#include "DisplayDevice.h"
-#include "FrontEnd/LayerCreationArgs.h"
-#include "Layer.h"
-#include "LayerRenderArea.h"
-#include "SurfaceFlinger.h"
-
-namespace android {
-
-LayerRenderArea::LayerRenderArea(sp<Layer> layer, frontend::LayerSnapshot layerSnapshot,
- const Rect& crop, ui::Size reqSize, ui::Dataspace reqDataSpace,
- const ui::Transform& layerTransform, const Rect& layerBufferSize,
- ftl::Flags<RenderArea::Options> options)
- : RenderArea(reqSize, CaptureFill::CLEAR, reqDataSpace, options),
- mLayer(std::move(layer)),
- mLayerSnapshot(std::move(layerSnapshot)),
- mLayerBufferSize(layerBufferSize),
- mCrop(crop),
- mTransform(layerTransform) {}
-
-const ui::Transform& LayerRenderArea::getTransform() const {
- return mTransform;
-}
-
-bool LayerRenderArea::isSecure() const {
- return mOptions.test(Options::CAPTURE_SECURE_LAYERS);
-}
-
-sp<const DisplayDevice> LayerRenderArea::getDisplayDevice() const {
- return nullptr;
-}
-
-Rect LayerRenderArea::getSourceCrop() const {
- if (mCrop.isEmpty()) {
- // TODO this should probably be mBounds instead of just buffer bounds
- return mLayerBufferSize;
- } else {
- return mCrop;
- }
-}
-
-} // namespace android
diff --git a/services/surfaceflinger/LayerRenderArea.h b/services/surfaceflinger/LayerRenderArea.h
deleted file mode 100644
index f72c7c7..0000000
--- a/services/surfaceflinger/LayerRenderArea.h
+++ /dev/null
@@ -1,57 +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.
- */
-
-#pragma once
-
-#include <string>
-
-#include <ui/GraphicTypes.h>
-#include <ui/Transform.h>
-#include <utils/StrongPointer.h>
-
-#include "RenderArea.h"
-
-namespace android {
-
-class DisplayDevice;
-class Layer;
-class SurfaceFlinger;
-
-class LayerRenderArea : public RenderArea {
-public:
- LayerRenderArea(sp<Layer> layer, frontend::LayerSnapshot layerSnapshot, const Rect& crop,
- ui::Size reqSize, ui::Dataspace reqDataSpace,
- const ui::Transform& layerTransform, const Rect& layerBufferSize,
- ftl::Flags<RenderArea::Options> options);
-
- const ui::Transform& getTransform() const override;
- bool isSecure() const override;
- sp<const DisplayDevice> getDisplayDevice() const override;
- Rect getSourceCrop() const override;
-
- sp<Layer> getParentLayer() const override { return mLayer; }
- const frontend::LayerSnapshot* getLayerSnapshot() const override { return &mLayerSnapshot; }
-
-private:
- const sp<Layer> mLayer;
- const frontend::LayerSnapshot mLayerSnapshot;
- const Rect mLayerBufferSize;
- const Rect mCrop;
-
- ui::Transform mTransform;
-};
-
-} // namespace android
diff --git a/services/surfaceflinger/OWNERS b/services/surfaceflinger/OWNERS
index fa0ecee..13edd16 100644
--- a/services/surfaceflinger/OWNERS
+++ b/services/surfaceflinger/OWNERS
@@ -12,6 +12,5 @@
ramindani@google.com
rnlee@google.com
sallyqi@google.com
-scroggo@google.com
vishnun@google.com
xwxw@google.com
diff --git a/services/surfaceflinger/RegionSamplingThread.cpp b/services/surfaceflinger/RegionSamplingThread.cpp
index d3483b0..1c4a11a 100644
--- a/services/surfaceflinger/RegionSamplingThread.cpp
+++ b/services/surfaceflinger/RegionSamplingThread.cpp
@@ -39,11 +39,8 @@
#include <string>
#include "DisplayDevice.h"
-#include "DisplayRenderArea.h"
#include "FrontEnd/LayerCreationArgs.h"
#include "Layer.h"
-#include "RenderAreaBuilder.h"
-#include "Scheduler/VsyncController.h"
#include "SurfaceFlinger.h"
namespace android {
@@ -259,6 +256,7 @@
ui::LayerStack layerStack;
ui::Transform::RotationFlags orientation;
ui::Size displaySize;
+ Rect layerStackSpaceRect;
{
// TODO(b/159112860): Don't keep sp<DisplayDevice> outside of SF main thread
@@ -267,6 +265,7 @@
layerStack = display->getLayerStack();
orientation = ui::Transform::toRotationFlags(display->getOrientation());
displaySize = display->getSize();
+ layerStackSpaceRect = display->getLayerStackSpaceRect();
}
std::vector<RegionSamplingThread::Descriptor> descriptors;
@@ -347,16 +346,20 @@
constexpr bool kGrayscale = false;
constexpr bool kIsProtected = false;
- SurfaceFlinger::RenderAreaBuilderVariant
- renderAreaBuilder(std::in_place_type<DisplayRenderAreaBuilder>, sampledBounds,
- sampledBounds.getSize(), ui::Dataspace::V0_SRGB, displayWeak,
- RenderArea::Options::CAPTURE_SECURE_LAYERS);
+ SurfaceFlinger::ScreenshotArgs screenshotArgs;
+ screenshotArgs.captureTypeVariant = displayWeak;
+ screenshotArgs.displayId = std::nullopt;
+ screenshotArgs.sourceCrop = sampledBounds.isEmpty() ? layerStackSpaceRect : sampledBounds;
+ screenshotArgs.reqSize = sampledBounds.getSize();
+ screenshotArgs.dataspace = ui::Dataspace::V0_SRGB;
+ screenshotArgs.isSecure = true;
+ screenshotArgs.seamlessTransition = false;
std::vector<std::pair<Layer*, sp<LayerFE>>> layers;
auto displayState =
- mFlinger.getSnapshotsFromMainThread(renderAreaBuilder, getLayerSnapshotsFn, layers);
+ mFlinger.getSnapshotsFromMainThread(screenshotArgs, getLayerSnapshotsFn, layers);
FenceResult fenceResult =
- mFlinger.captureScreenshot(renderAreaBuilder, buffer, kRegionSampling, kGrayscale,
+ mFlinger.captureScreenshot(screenshotArgs, buffer, kRegionSampling, kGrayscale,
kIsProtected, nullptr, displayState, layers)
.get();
if (fenceResult.ok()) {
diff --git a/services/surfaceflinger/RenderArea.h b/services/surfaceflinger/RenderArea.h
deleted file mode 100644
index aa66ccf..0000000
--- a/services/surfaceflinger/RenderArea.h
+++ /dev/null
@@ -1,98 +0,0 @@
-#pragma once
-
-#include <ui/GraphicTypes.h>
-#include <ui/Transform.h>
-
-#include <functional>
-
-#include "FrontEnd/LayerSnapshot.h"
-#include "Layer.h"
-
-namespace android {
-
-class DisplayDevice;
-
-// RenderArea describes a rectangular area that layers can be rendered to.
-//
-// There is a logical render area and a physical render area. When a layer is
-// rendered to the render area, it is first transformed and clipped to the logical
-// render area. The transformed and clipped layer is then projected onto the
-// physical render area.
-class RenderArea {
-public:
- enum class CaptureFill {CLEAR, OPAQUE};
- enum class Options {
- // If not set, the secure layer would be blacked out or skipped
- // when rendered to an insecure render area
- CAPTURE_SECURE_LAYERS = 1 << 0,
-
- // If set, the render result may be used for system animations
- // that must preserve the exact colors of the display
- HINT_FOR_SEAMLESS_TRANSITION = 1 << 1,
- };
- static float getCaptureFillValue(CaptureFill captureFill);
-
- RenderArea(ui::Size reqSize, CaptureFill captureFill, ui::Dataspace reqDataSpace,
- ftl::Flags<Options> options)
- : mOptions(options),
- mReqSize(reqSize),
- mReqDataSpace(reqDataSpace),
- mCaptureFill(captureFill) {}
-
- virtual ~RenderArea() = default;
-
- // Returns true if the render area is secure. A secure layer should be
- // blacked out / skipped when rendered to an insecure render area.
- virtual bool isSecure() const = 0;
-
- // Returns the transform to be applied on layers to transform them into
- // the logical render area.
- virtual const ui::Transform& getTransform() const = 0;
-
- // Returns the source crop of the render area. The source crop defines
- // how layers are projected from the logical render area onto the physical
- // render area. It can be larger than the logical render area. It can
- // also be optionally rotated.
- //
- // The source crop is specified in layer space (when rendering a layer and
- // its children), or in layer-stack space (when rendering all layers visible
- // on the display).
- virtual Rect getSourceCrop() const = 0;
-
- // Returns the size of the physical render area.
- int getReqWidth() const { return mReqSize.width; }
- int getReqHeight() const { return mReqSize.height; }
-
- // Returns the composition data space of the render area.
- ui::Dataspace getReqDataSpace() const { return mReqDataSpace; }
-
- // Returns the fill color of the physical render area. Regions not
- // covered by any rendered layer should be filled with this color.
- CaptureFill getCaptureFill() const { return mCaptureFill; }
-
- virtual sp<const DisplayDevice> getDisplayDevice() const = 0;
-
- // If this is a LayerRenderArea, return the root layer of the
- // capture operation.
- virtual sp<Layer> getParentLayer() const { return nullptr; }
-
- // If this is a LayerRenderArea, return the layer snapshot
- // of the root layer of the capture operation
- virtual const frontend::LayerSnapshot* getLayerSnapshot() const { return nullptr; }
-
- // Returns whether the render result may be used for system animations that
- // must preserve the exact colors of the display.
- bool getHintForSeamlessTransition() const {
- return mOptions.test(Options::HINT_FOR_SEAMLESS_TRANSITION);
- }
-
-protected:
- ftl::Flags<Options> mOptions;
-
-private:
- const ui::Size mReqSize;
- const ui::Dataspace mReqDataSpace;
- const CaptureFill mCaptureFill;
-};
-
-} // namespace android
diff --git a/services/surfaceflinger/RenderAreaBuilder.h b/services/surfaceflinger/RenderAreaBuilder.h
deleted file mode 100644
index 599fa7e..0000000
--- a/services/surfaceflinger/RenderAreaBuilder.h
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright 2024 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 "DisplayDevice.h"
-#include "DisplayRenderArea.h"
-#include "LayerRenderArea.h"
-#include "ui/Size.h"
-#include "ui/Transform.h"
-
-namespace android {
-/**
- * A parameter object for creating a render area
- */
-struct RenderAreaBuilder {
- // Source crop of the render area
- Rect crop;
-
- // Size of the physical render area
- ui::Size reqSize;
-
- // Composition data space of the render area
- ui::Dataspace reqDataSpace;
-
- ftl::Flags<RenderArea::Options> options;
- virtual std::unique_ptr<RenderArea> build() const = 0;
-
- RenderAreaBuilder(Rect crop, ui::Size reqSize, ui::Dataspace reqDataSpace,
- ftl::Flags<RenderArea::Options> options)
- : crop(crop), reqSize(reqSize), reqDataSpace(reqDataSpace), options(options) {}
-
- virtual ~RenderAreaBuilder() = default;
-};
-
-struct DisplayRenderAreaBuilder : RenderAreaBuilder {
- DisplayRenderAreaBuilder(Rect crop, ui::Size reqSize, ui::Dataspace reqDataSpace,
- wp<const DisplayDevice> displayWeak,
- ftl::Flags<RenderArea::Options> options)
- : RenderAreaBuilder(crop, reqSize, reqDataSpace, options), displayWeak(displayWeak) {}
-
- // Display that render area will be on
- wp<const DisplayDevice> displayWeak;
-
- std::unique_ptr<RenderArea> build() const override {
- return DisplayRenderArea::create(displayWeak, crop, reqSize, reqDataSpace, options);
- }
-};
-
-struct LayerRenderAreaBuilder : RenderAreaBuilder {
- LayerRenderAreaBuilder(Rect crop, ui::Size reqSize, ui::Dataspace reqDataSpace, sp<Layer> layer,
- bool childrenOnly, ftl::Flags<RenderArea::Options> options)
- : RenderAreaBuilder(crop, reqSize, reqDataSpace, options),
- layer(layer),
- childrenOnly(childrenOnly) {}
-
- // Root layer of the render area
- sp<Layer> layer;
-
- // Layer snapshot of the root layer
- frontend::LayerSnapshot layerSnapshot;
-
- // Transform to be applied on the layers to transform them
- // into the logical render area
- ui::Transform layerTransform{ui::Transform()};
-
- // Buffer bounds
- Rect layerBufferSize{Rect()};
-
- // If false, transform is inverted from the parent snapshot
- bool childrenOnly;
-
- // Uses parent snapshot to determine layer transform and buffer size
- void setLayerSnapshot(const frontend::LayerSnapshot& parentSnapshot) {
- layerSnapshot = parentSnapshot;
- if (!childrenOnly) {
- layerTransform = parentSnapshot.localTransform.inverse();
- }
- layerBufferSize = parentSnapshot.bufferSize;
- }
-
- std::unique_ptr<RenderArea> build() const override {
- return std::make_unique<LayerRenderArea>(layer, std::move(layerSnapshot), crop, reqSize,
- reqDataSpace, layerTransform, layerBufferSize,
- options);
- }
-};
-
-} // namespace android
\ No newline at end of file
diff --git a/services/surfaceflinger/Scheduler/EventThread.cpp b/services/surfaceflinger/Scheduler/EventThread.cpp
index 0efc396..c37b965 100644
--- a/services/surfaceflinger/Scheduler/EventThread.cpp
+++ b/services/surfaceflinger/Scheduler/EventThread.cpp
@@ -45,7 +45,7 @@
#include <common/FlagManager.h>
#include <scheduler/FrameRateMode.h>
#include <scheduler/VsyncConfig.h>
-#include "FrameTimeline.h"
+#include "FrameTimeline/FrameTimeline.h"
#include "VSyncDispatch.h"
#include "EventThread.h"
@@ -86,36 +86,43 @@
std::string toString(const DisplayEventReceiver::Event& event) {
switch (event.header.type) {
- case DisplayEventReceiver::DISPLAY_EVENT_HOTPLUG:
+ case DisplayEventType::DISPLAY_EVENT_HOTPLUG:
return StringPrintf("Hotplug{displayId=%s, %s}",
to_string(event.header.displayId).c_str(),
event.hotplug.connected ? "connected" : "disconnected");
- case DisplayEventReceiver::DISPLAY_EVENT_VSYNC:
+ case DisplayEventType::DISPLAY_EVENT_VSYNC:
return StringPrintf("VSync{displayId=%s, count=%u, expectedPresentationTime=%" PRId64
"}",
to_string(event.header.displayId).c_str(), event.vsync.count,
event.vsync.vsyncData.preferredExpectedPresentationTime());
- case DisplayEventReceiver::DISPLAY_EVENT_MODE_CHANGE:
+ case DisplayEventType::DISPLAY_EVENT_MODE_CHANGE:
return StringPrintf("ModeChanged{displayId=%s, modeId=%u}",
to_string(event.header.displayId).c_str(), event.modeChange.modeId);
- case DisplayEventReceiver::DISPLAY_EVENT_HDCP_LEVELS_CHANGE:
+ case DisplayEventType::DISPLAY_EVENT_HDCP_LEVELS_CHANGE:
return StringPrintf("HdcpLevelsChange{displayId=%s, connectedLevel=%d, maxLevel=%d}",
to_string(event.header.displayId).c_str(),
event.hdcpLevelsChange.connectedLevel,
event.hdcpLevelsChange.maxLevel);
- case DisplayEventReceiver::DISPLAY_EVENT_MODE_REJECTION:
+ case DisplayEventType::DISPLAY_EVENT_MODE_REJECTION:
return StringPrintf("ModeRejected{displayId=%s, modeId=%u}",
to_string(event.header.displayId).c_str(),
event.modeRejection.modeId);
- default:
- return "Event{}";
+ case DisplayEventType::DISPLAY_EVENT_FRAME_RATE_OVERRIDE:
+ return StringPrintf("FrameRateOverride{displayId=%s, frameRateHz=%f}",
+ to_string(event.header.displayId).c_str(),
+ event.frameRateOverride.frameRateHz);
+ case DisplayEventType::DISPLAY_EVENT_FRAME_RATE_OVERRIDE_FLUSH:
+ return StringPrintf("FrameRateOverrideFlush{displayId=%s}",
+ to_string(event.header.displayId).c_str());
+ case DisplayEventType::DISPLAY_EVENT_NULL:
+ return "NULL";
}
}
DisplayEventReceiver::Event makeHotplug(PhysicalDisplayId displayId, nsecs_t timestamp,
bool connected) {
DisplayEventReceiver::Event event;
- event.header = {DisplayEventReceiver::DISPLAY_EVENT_HOTPLUG, displayId, timestamp};
+ event.header = {DisplayEventType::DISPLAY_EVENT_HOTPLUG, displayId, timestamp};
event.hotplug.connected = connected;
return event;
}
@@ -123,7 +130,7 @@
DisplayEventReceiver::Event makeHotplugError(nsecs_t timestamp, int32_t connectionError) {
DisplayEventReceiver::Event event;
PhysicalDisplayId unusedDisplayId;
- event.header = {DisplayEventReceiver::DISPLAY_EVENT_HOTPLUG, unusedDisplayId, timestamp};
+ event.header = {DisplayEventType::DISPLAY_EVENT_HOTPLUG, unusedDisplayId, timestamp};
event.hotplug.connected = false;
event.hotplug.connectionError = connectionError;
return event;
@@ -133,7 +140,7 @@
uint32_t count, nsecs_t expectedPresentationTime,
nsecs_t deadlineTimestamp) {
DisplayEventReceiver::Event event;
- event.header = {DisplayEventReceiver::DISPLAY_EVENT_VSYNC, displayId, timestamp};
+ event.header = {DisplayEventType::DISPLAY_EVENT_VSYNC, displayId, timestamp};
event.vsync.count = count;
event.vsync.vsyncData.preferredFrameTimelineIndex = 0;
// Temporarily store the current vsync information in frameTimelines[0], marked as
@@ -148,7 +155,7 @@
DisplayEventReceiver::Event makeModeChanged(const scheduler::FrameRateMode& mode) {
DisplayEventReceiver::Event event;
- event.header = {DisplayEventReceiver::DISPLAY_EVENT_MODE_CHANGE,
+ event.header = {DisplayEventType::DISPLAY_EVENT_MODE_CHANGE,
mode.modePtr->getPhysicalDisplayId(), systemTime()};
event.modeChange.modeId = ftl::to_underlying(mode.modePtr->getId());
event.modeChange.vsyncPeriod = mode.fps.getPeriodNsecs();
@@ -160,7 +167,7 @@
return DisplayEventReceiver::Event{
.header =
DisplayEventReceiver::Event::Header{
- .type = DisplayEventReceiver::DISPLAY_EVENT_FRAME_RATE_OVERRIDE,
+ .type = DisplayEventType::DISPLAY_EVENT_FRAME_RATE_OVERRIDE,
.displayId = displayId,
.timestamp = systemTime(),
},
@@ -171,7 +178,7 @@
DisplayEventReceiver::Event makeFrameRateOverrideFlushEvent(PhysicalDisplayId displayId) {
return DisplayEventReceiver::Event{
.header = DisplayEventReceiver::Event::Header{
- .type = DisplayEventReceiver::DISPLAY_EVENT_FRAME_RATE_OVERRIDE_FLUSH,
+ .type = DisplayEventType::DISPLAY_EVENT_FRAME_RATE_OVERRIDE_FLUSH,
.displayId = displayId,
.timestamp = systemTime(),
}};
@@ -182,7 +189,7 @@
return DisplayEventReceiver::Event{
.header =
DisplayEventReceiver::Event::Header{
- .type = DisplayEventReceiver::DISPLAY_EVENT_HDCP_LEVELS_CHANGE,
+ .type = DisplayEventType::DISPLAY_EVENT_HDCP_LEVELS_CHANGE,
.displayId = displayId,
.timestamp = systemTime(),
},
@@ -195,7 +202,7 @@
return DisplayEventReceiver::Event{
.header =
DisplayEventReceiver::Event::Header{
- .type = DisplayEventReceiver::DISPLAY_EVENT_MODE_REJECTION,
+ .type = DisplayEventType::DISPLAY_EVENT_MODE_REJECTION,
.displayId = displayId,
.timestamp = systemTime(),
},
@@ -263,10 +270,10 @@
return size < 0 ? status_t(size) : status_t(NO_ERROR);
};
- if (event.header.type == DisplayEventReceiver::DISPLAY_EVENT_FRAME_RATE_OVERRIDE ||
- event.header.type == DisplayEventReceiver::DISPLAY_EVENT_FRAME_RATE_OVERRIDE_FLUSH) {
+ if (event.header.type == DisplayEventType::DISPLAY_EVENT_FRAME_RATE_OVERRIDE ||
+ event.header.type == DisplayEventType::DISPLAY_EVENT_FRAME_RATE_OVERRIDE_FLUSH) {
mPendingEvents.emplace_back(event);
- if (event.header.type == DisplayEventReceiver::DISPLAY_EVENT_FRAME_RATE_OVERRIDE) {
+ if (event.header.type == DisplayEventType::DISPLAY_EVENT_FRAME_RATE_OVERRIDE) {
return status_t(NO_ERROR);
}
@@ -524,7 +531,7 @@
event = mPendingEvents.front();
mPendingEvents.pop_front();
- if (event->header.type == DisplayEventReceiver::DISPLAY_EVENT_HOTPLUG) {
+ if (event->header.type == DisplayEventType::DISPLAY_EVENT_HOTPLUG) {
if (event->hotplug.connectionError == 0) {
if (event->hotplug.connected && !mVSyncState) {
mVSyncState.emplace();
@@ -636,18 +643,21 @@
};
switch (event.header.type) {
- case DisplayEventReceiver::DISPLAY_EVENT_HOTPLUG:
+ case DisplayEventType::DISPLAY_EVENT_HOTPLUG:
return true;
- case DisplayEventReceiver::DISPLAY_EVENT_HDCP_LEVELS_CHANGE:
+ case DisplayEventType::DISPLAY_EVENT_HDCP_LEVELS_CHANGE:
return true;
- case DisplayEventReceiver::DISPLAY_EVENT_MODE_CHANGE: {
+ case DisplayEventType::DISPLAY_EVENT_MODE_CHANGE: {
return connection->mEventRegistration.test(
gui::ISurfaceComposer::EventRegistration::modeChanged);
}
- case DisplayEventReceiver::DISPLAY_EVENT_VSYNC:
+ case DisplayEventType::DISPLAY_EVENT_MODE_REJECTION:
+ return true;
+
+ case DisplayEventType::DISPLAY_EVENT_VSYNC:
switch (connection->vsyncRequest) {
case VSyncRequest::None:
return false;
@@ -673,13 +683,12 @@
return event.vsync.count % vsyncPeriod(connection->vsyncRequest) == 0;
}
- case DisplayEventReceiver::DISPLAY_EVENT_FRAME_RATE_OVERRIDE:
+ case DisplayEventType::DISPLAY_EVENT_FRAME_RATE_OVERRIDE:
[[fallthrough]];
- case DisplayEventReceiver::DISPLAY_EVENT_FRAME_RATE_OVERRIDE_FLUSH:
+ case DisplayEventType::DISPLAY_EVENT_FRAME_RATE_OVERRIDE_FLUSH:
return connection->mEventRegistration.test(
gui::ISurfaceComposer::EventRegistration::frameRateOverride);
-
- default:
+ case DisplayEventType::DISPLAY_EVENT_NULL:
return false;
}
}
@@ -758,7 +767,7 @@
ftl::SmallVector<uid_t, 10> uidsPostedQueuedBuffers;
for (const auto& consumer : consumers) {
DisplayEventReceiver::Event copy = event;
- if (event.header.type == DisplayEventReceiver::DISPLAY_EVENT_VSYNC) {
+ if (event.header.type == DisplayEventType::DISPLAY_EVENT_VSYNC) {
const Period frameInterval = mCallback.getVsyncPeriod(consumer->mOwnerUid);
copy.vsync.vsyncData.frameInterval = frameInterval.ns();
generateFrameTimeline(copy.vsync.vsyncData, frameInterval.ns(), copy.header.timestamp,
@@ -793,7 +802,7 @@
for (auto uid : uidsPostedQueuedBuffers) {
mBufferStuffedUids.erase(uid);
}
- if (event.header.type == DisplayEventReceiver::DISPLAY_EVENT_VSYNC &&
+ if (event.header.type == DisplayEventType::DISPLAY_EVENT_VSYNC &&
FlagManager::getInstance().vrr_config()) {
mLastCommittedVsyncTime =
TimePoint::fromNs(event.vsync.vsyncData.preferredExpectedPresentationTime());
diff --git a/services/surfaceflinger/Scheduler/MessageQueue.cpp b/services/surfaceflinger/Scheduler/MessageQueue.cpp
index 2e1f938..91a798e 100644
--- a/services/surfaceflinger/Scheduler/MessageQueue.cpp
+++ b/services/surfaceflinger/Scheduler/MessageQueue.cpp
@@ -24,7 +24,7 @@
#include <scheduler/interface/ICompositor.h>
#include "EventThread.h"
-#include "FrameTimeline.h"
+#include "FrameTimeline/FrameTimeline.h"
#include "MessageQueue.h"
namespace android::impl {
diff --git a/services/surfaceflinger/ScreenCaptureOutput.cpp b/services/surfaceflinger/ScreenCaptureOutput.cpp
index 5f71b88..7123905 100644
--- a/services/surfaceflinger/ScreenCaptureOutput.cpp
+++ b/services/surfaceflinger/ScreenCaptureOutput.cpp
@@ -29,11 +29,15 @@
std::shared_ptr<ScreenCaptureOutput> createScreenCaptureOutput(ScreenCaptureOutputArgs args) {
std::shared_ptr<ScreenCaptureOutput> output = compositionengine::impl::createOutputTemplated<
- ScreenCaptureOutput, compositionengine::CompositionEngine, const RenderArea&,
+ ScreenCaptureOutput, compositionengine::CompositionEngine,
+ /* sourceCrop */ const Rect, std::optional<DisplayId>,
const compositionengine::Output::ColorProfile&,
- bool>(args.compositionEngine, args.renderArea, args.colorProfile, args.regionSampling,
- args.dimInGammaSpaceForEnhancedScreenshots, args.enableLocalTonemapping);
- output->editState().isSecure = args.renderArea.isSecure();
+ /* layerAlpha */ float,
+ /* regionSampling */ bool>(args.compositionEngine, args.sourceCrop, args.displayId,
+ args.colorProfile, args.layerAlpha, args.regionSampling,
+ args.dimInGammaSpaceForEnhancedScreenshots,
+ args.enableLocalTonemapping);
+ output->editState().isSecure = args.isSecure;
output->editState().isProtected = args.isProtected;
output->setCompositionEnabled(true);
output->setLayerFilter({args.layerStack});
@@ -47,16 +51,16 @@
.setHasWideColorGamut(true)
.Build()));
- const Rect& sourceCrop = args.renderArea.getSourceCrop();
+ const Rect& sourceCrop = args.sourceCrop;
const ui::Rotation orientation = ui::ROTATION_0;
output->setDisplaySize({sourceCrop.getWidth(), sourceCrop.getHeight()});
output->setProjection(orientation, sourceCrop,
- {args.renderArea.getReqWidth(), args.renderArea.getReqHeight()});
+ {args.reqBufferSize.width, args.reqBufferSize.height});
{
std::string name = args.regionSampling ? "RegionSampling" : "ScreenCaptureOutput";
- if (auto displayDevice = args.renderArea.getDisplayDevice()) {
- base::StringAppendF(&name, " for %" PRIu64, displayDevice->getId().value);
+ if (args.displayId) {
+ base::StringAppendF(&name, " for %" PRIu64, args.displayId.value().value);
}
output->setName(name);
}
@@ -64,11 +68,14 @@
}
ScreenCaptureOutput::ScreenCaptureOutput(
- const RenderArea& renderArea, const compositionengine::Output::ColorProfile& colorProfile,
+ const Rect sourceCrop, std::optional<DisplayId> displayId,
+ const compositionengine::Output::ColorProfile& colorProfile, float layerAlpha,
bool regionSampling, bool dimInGammaSpaceForEnhancedScreenshots,
bool enableLocalTonemapping)
- : mRenderArea(renderArea),
+ : mSourceCrop(sourceCrop),
+ mDisplayId(displayId),
mColorProfile(colorProfile),
+ mLayerAlpha(layerAlpha),
mRegionSampling(regionSampling),
mDimInGammaSpaceForEnhancedScreenshots(dimInGammaSpaceForEnhancedScreenshots),
mEnableLocalTonemapping(enableLocalTonemapping) {}
@@ -83,7 +90,7 @@
const std::shared_ptr<renderengine::ExternalTexture>& buffer) const {
auto clientCompositionDisplay =
compositionengine::impl::Output::generateClientCompositionDisplaySettings(buffer);
- clientCompositionDisplay.clip = mRenderArea.getSourceCrop();
+ clientCompositionDisplay.clip = mSourceCrop;
auto renderIntent = static_cast<ui::RenderIntent>(clientCompositionDisplay.renderIntent);
if (mDimInGammaSpaceForEnhancedScreenshots && renderIntent != ui::RenderIntent::COLORIMETRIC &&
@@ -130,8 +137,8 @@
}
std::vector<aidl::android::hardware::graphics::composer3::Luts> luts;
- if (auto displayDevice = mRenderArea.getDisplayDevice()) {
- const auto id = PhysicalDisplayId::tryCast(displayDevice->getId());
+ if (mDisplayId) {
+ const auto id = PhysicalDisplayId::tryCast(mDisplayId.value());
if (id) {
auto& hwc = getCompositionEngine().getHwComposer();
hwc.getLuts(*id, buffers, &luts);
@@ -201,14 +208,15 @@
}
}
- Rect sourceCrop = mRenderArea.getSourceCrop();
compositionengine::LayerFE::LayerSettings fillLayer;
fillLayer.source.buffer.buffer = nullptr;
fillLayer.source.solidColor = half3(0.0f, 0.0f, 0.0f);
fillLayer.geometry.boundaries =
- FloatRect(static_cast<float>(sourceCrop.left), static_cast<float>(sourceCrop.top),
- static_cast<float>(sourceCrop.right), static_cast<float>(sourceCrop.bottom));
- fillLayer.alpha = half(RenderArea::getCaptureFillValue(mRenderArea.getCaptureFill()));
+ FloatRect(static_cast<float>(mSourceCrop.left), static_cast<float>(mSourceCrop.top),
+ static_cast<float>(mSourceCrop.right),
+ static_cast<float>(mSourceCrop.bottom));
+
+ fillLayer.alpha = half(mLayerAlpha);
clientCompositionLayers.insert(clientCompositionLayers.begin(), fillLayer);
return clientCompositionLayers;
diff --git a/services/surfaceflinger/ScreenCaptureOutput.h b/services/surfaceflinger/ScreenCaptureOutput.h
index 444a28f..b3e98b1 100644
--- a/services/surfaceflinger/ScreenCaptureOutput.h
+++ b/services/surfaceflinger/ScreenCaptureOutput.h
@@ -22,23 +22,25 @@
#include <ui/Rect.h>
#include <unordered_map>
-#include "RenderArea.h"
-
namespace android {
struct ScreenCaptureOutputArgs {
const compositionengine::CompositionEngine& compositionEngine;
const compositionengine::Output::ColorProfile& colorProfile;
- const RenderArea& renderArea;
ui::LayerStack layerStack;
+ Rect sourceCrop;
std::shared_ptr<renderengine::ExternalTexture> buffer;
+ std::optional<DisplayId> displayId;
+ ui::Size reqBufferSize;
float sdrWhitePointNits;
float displayBrightnessNits;
// Counterintuitively, when targetBrightness > 1.0 then dim the scene.
float targetBrightness;
+ float layerAlpha;
bool regionSampling;
bool treat170mAsSrgb;
bool dimInGammaSpaceForEnhancedScreenshots;
+ bool isSecure = false;
bool isProtected = false;
bool enableLocalTonemapping = false;
};
@@ -49,10 +51,10 @@
// SurfaceFlinger::captureLayers and SurfaceFlinger::captureDisplay.
class ScreenCaptureOutput : public compositionengine::impl::Output {
public:
- ScreenCaptureOutput(const RenderArea& renderArea,
+ ScreenCaptureOutput(const Rect sourceCrop, std::optional<DisplayId> displayId,
const compositionengine::Output::ColorProfile& colorProfile,
- bool regionSampling, bool dimInGammaSpaceForEnhancedScreenshots,
- bool enableLocalTonemapping);
+ float layerAlpha, bool regionSampling,
+ bool dimInGammaSpaceForEnhancedScreenshots, bool enableLocalTonemapping);
void updateColorProfile(const compositionengine::CompositionRefreshArgs&) override;
@@ -67,8 +69,10 @@
private:
std::unordered_map<int32_t, aidl::android::hardware::graphics::composer3::Luts> generateLuts();
- const RenderArea& mRenderArea;
+ const Rect mSourceCrop;
+ const std::optional<DisplayId> mDisplayId;
const compositionengine::Output::ColorProfile& mColorProfile;
+ const float mLayerAlpha;
const bool mRegionSampling;
const bool mDimInGammaSpaceForEnhancedScreenshots;
const bool mEnableLocalTonemapping;
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index eecdd72..1163390 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -137,7 +137,6 @@
#include "DisplayHardware/FramebufferSurface.h"
#include "DisplayHardware/Hal.h"
#include "DisplayHardware/VirtualDisplaySurface.h"
-#include "DisplayRenderArea.h"
#include "Effects/Daltonizer.h"
#include "FpsReporter.h"
#include "FrameTimeline/FrameTimeline.h"
@@ -151,14 +150,12 @@
#include "Jank/JankTracker.h"
#include "Layer.h"
#include "LayerProtoHelper.h"
-#include "LayerRenderArea.h"
#include "LayerVector.h"
#include "MutexUtils.h"
#include "NativeWindowSurface.h"
#include "PowerAdvisor/PowerAdvisor.h"
#include "PowerAdvisor/Workload.h"
#include "RegionSamplingThread.h"
-#include "RenderAreaBuilder.h"
#include "Scheduler/EventThread.h"
#include "Scheduler/LayerHistory.h"
#include "Scheduler/Scheduler.h"
@@ -1166,8 +1163,8 @@
}
Mutex::Autolock lock(mStateLock);
- const auto id = DisplayId::fromValue<PhysicalDisplayId>(static_cast<uint64_t>(displayId));
- const auto displayOpt = mPhysicalDisplays.get(*id).and_then(getDisplayDeviceAndSnapshot());
+ const PhysicalDisplayId id = PhysicalDisplayId::fromValue(static_cast<uint64_t>(displayId));
+ const auto displayOpt = mPhysicalDisplays.get(id).and_then(getDisplayDeviceAndSnapshot());
if (!displayOpt) {
return NAME_NOT_FOUND;
@@ -1289,9 +1286,9 @@
Mutex::Autolock lock(mStateLock);
- const auto id_ =
- DisplayId::fromValue<PhysicalDisplayId>(static_cast<uint64_t>(physicalDisplayId));
- const auto displayOpt = mPhysicalDisplays.get(*id_).and_then(getDisplayDeviceAndSnapshot());
+ const PhysicalDisplayId id =
+ PhysicalDisplayId::fromValue(static_cast<uint64_t>(physicalDisplayId));
+ const auto displayOpt = mPhysicalDisplays.get(id).and_then(getDisplayDeviceAndSnapshot());
if (!displayOpt) {
return NAME_NOT_FOUND;
@@ -2980,6 +2977,8 @@
int index = 0;
ftl::StaticVector<char, WorkloadTracer::COMPOSITION_SUMMARY_SIZE> compositionSummary;
auto lastLayerStack = ui::INVALID_LAYER_STACK;
+
+ uint64_t prevOverrideBufferId = 0;
for (auto& [layer, layerFE] : layers) {
CompositionResult compositionResult{layerFE->stealCompositionResult()};
if (lastLayerStack != layerFE->mSnapshot->outputFilter.layerStack) {
@@ -2989,8 +2988,37 @@
}
lastLayerStack = layerFE->mSnapshot->outputFilter.layerStack;
}
+
+ // If there are N layers in a cached set they should all share the same buffer id.
+ // The first layer in the cached set will be not skipped and layers 1..N-1 will be skipped.
+ // We expect all layers in the cached set to be marked as composited by HWC.
+ // Here is a made up example of how it is visualized
+ //
+ // [b:rrc][s:cc]
+ //
+ // This should be interpreted to mean that there are 2 cached sets.
+ // So there are only 2 non skipped layers -- b and s.
+ // The layers rrc and cc are flattened into layers b and s respectively.
+ const LayerFE::HwcLayerDebugState &hwcState = layerFE->getLastHwcState();
+ if (hwcState.overrideBufferId != prevOverrideBufferId) {
+ // End the existing run.
+ if (prevOverrideBufferId) {
+ compositionSummary.push_back(']');
+ }
+ // Start a new run.
+ if (hwcState.overrideBufferId) {
+ compositionSummary.push_back('[');
+ }
+ }
+
compositionSummary.push_back(
- layerFE->mSnapshot->classifyCompositionForDebug(layerFE->getHwcCompositionType()));
+ layerFE->mSnapshot->classifyCompositionForDebug(hwcState));
+
+ if (hwcState.overrideBufferId && !hwcState.wasSkipped) {
+ compositionSummary.push_back(':');
+ }
+ prevOverrideBufferId = hwcState.overrideBufferId;
+
if (layerFE->mSnapshot->hasEffect()) {
compositedWorkload |= adpf::Workload::EFFECTS;
}
@@ -3002,6 +3030,10 @@
mActivePictureTracker.onLayerComposed(*layer, *layerFE, compositionResult);
}
}
+ // End the last run.
+ if (prevOverrideBufferId) {
+ compositionSummary.push_back(']');
+ }
// Concisely describe the layers composited this frame using single chars. GPU composited layers
// are uppercase, DPU composited are lowercase. Special chars denote effects (blur, shadow,
@@ -6734,8 +6766,9 @@
return getDefaultDisplayDevice()->getDisplayToken().promote();
}
- if (const auto id = DisplayId::fromValue<PhysicalDisplayId>(value)) {
- return getPhysicalDisplayToken(*id);
+ if (const auto token =
+ getPhysicalDisplayToken(PhysicalDisplayId::fromValue(value))) {
+ return token;
}
ALOGE("Invalid physical display ID");
@@ -6833,10 +6866,10 @@
case 1040: {
auto future = mScheduler->schedule([&] {
n = data.readInt32();
- std::optional<PhysicalDisplayId> inputId = std::nullopt;
+ PhysicalDisplayId inputId;
if (uint64_t inputDisplayId; data.readUint64(&inputDisplayId) == NO_ERROR) {
- inputId = DisplayId::fromValue<PhysicalDisplayId>(inputDisplayId);
- if (!inputId || getPhysicalDisplayToken(*inputId)) {
+ inputId = PhysicalDisplayId::fromValue(inputDisplayId);
+ if (!getPhysicalDisplayToken(inputId)) {
ALOGE("No display with id: %" PRIu64, inputDisplayId);
return NAME_NOT_FOUND;
}
@@ -6845,7 +6878,7 @@
Mutex::Autolock lock(mStateLock);
mLayerCachingEnabled = n != 0;
for (const auto& [_, display] : mDisplays) {
- if (!inputId || *inputId == display->getPhysicalId()) {
+ if (inputId == display->getPhysicalId()) {
display->enableLayerCaching(mLayerCachingEnabled);
}
}
@@ -6928,11 +6961,10 @@
int64_t arg1 = data.readInt64();
int64_t arg2 = data.readInt64();
// Enable mirroring for one display
- const auto display1id = DisplayId::fromValue(arg1);
auto mirrorRoot = SurfaceComposerClient::getDefault()->mirrorDisplay(
- display1id.value());
- auto id2 = DisplayId::fromValue<PhysicalDisplayId>(arg2);
- const auto token2 = getPhysicalDisplayToken(*id2);
+ DisplayId::fromValue(arg1));
+ const auto token2 =
+ getPhysicalDisplayToken(PhysicalDisplayId::fromValue(arg2));
ui::LayerStack layerStack;
{
Mutex::Autolock lock(mStateLock);
@@ -7220,9 +7252,13 @@
}
wp<const DisplayDevice> displayWeak;
+ DisplayId displayId;
ui::LayerStack layerStack;
ui::Size reqSize(args.width, args.height);
std::unordered_set<uint32_t> excludeLayerIds;
+ Rect layerStackSpaceRect;
+ bool displayIsSecure;
+
{
Mutex::Autolock lock(mStateLock);
sp<DisplayDevice> display = getDisplayDeviceLocked(args.displayToken);
@@ -7232,11 +7268,14 @@
return;
}
displayWeak = display;
+ displayId = display->getId();
layerStack = display->getLayerStack();
+ displayIsSecure = display->isSecure();
+ layerStackSpaceRect = display->getLayerStackSpaceRect();
// set the requested width/height to the logical display layer stack rect size by default
if (args.width == 0 || args.height == 0) {
- reqSize = display->getLayerStackSpaceRect().getSize();
+ reqSize = layerStackSpaceRect.getSize();
}
for (const auto& handle : captureArgs.excludeHandles) {
@@ -7255,16 +7294,19 @@
getLayerSnapshotsForScreenshots(layerStack, captureArgs.uid,
std::move(excludeLayerIds));
- ftl::Flags<RenderArea::Options> options;
- if (captureArgs.captureSecureLayers) options |= RenderArea::Options::CAPTURE_SECURE_LAYERS;
- if (captureArgs.hintForSeamlessTransition)
- options |= RenderArea::Options::HINT_FOR_SEAMLESS_TRANSITION;
- captureScreenCommon(RenderAreaBuilderVariant(std::in_place_type<DisplayRenderAreaBuilder>,
- gui::aidl_utils::fromARect(captureArgs.sourceCrop),
- reqSize,
- static_cast<ui::Dataspace>(captureArgs.dataspace),
- displayWeak, options),
- getLayerSnapshotsFn, reqSize,
+ ScreenshotArgs screenshotArgs;
+ screenshotArgs.captureTypeVariant = displayWeak;
+ screenshotArgs.displayId = displayId;
+ screenshotArgs.sourceCrop = gui::aidl_utils::fromARect(captureArgs.sourceCrop);
+ if (screenshotArgs.sourceCrop.isEmpty()) {
+ screenshotArgs.sourceCrop = layerStackSpaceRect;
+ }
+ screenshotArgs.reqSize = reqSize;
+ screenshotArgs.dataspace = static_cast<ui::Dataspace>(captureArgs.dataspace);
+ screenshotArgs.isSecure = captureArgs.captureSecureLayers && displayIsSecure;
+ screenshotArgs.seamlessTransition = captureArgs.hintForSeamlessTransition;
+
+ captureScreenCommon(screenshotArgs, getLayerSnapshotsFn, reqSize,
static_cast<ui::PixelFormat>(captureArgs.pixelFormat),
captureArgs.allowProtected, captureArgs.grayscale, captureListener);
}
@@ -7274,6 +7316,9 @@
ui::LayerStack layerStack;
wp<const DisplayDevice> displayWeak;
ui::Size size;
+ Rect layerStackSpaceRect;
+ bool displayIsSecure;
+
{
Mutex::Autolock lock(mStateLock);
@@ -7286,7 +7331,9 @@
displayWeak = display;
layerStack = display->getLayerStack();
+ layerStackSpaceRect = display->getLayerStackSpaceRect();
size = display->getLayerStackSpaceRect().getSize();
+ displayIsSecure = display->isSecure();
}
size.width *= args.frameScaleX;
@@ -7315,15 +7362,18 @@
constexpr bool kAllowProtected = false;
constexpr bool kGrayscale = false;
- ftl::Flags<RenderArea::Options> options;
- if (args.hintForSeamlessTransition)
- options |= RenderArea::Options::HINT_FOR_SEAMLESS_TRANSITION;
- captureScreenCommon(RenderAreaBuilderVariant(std::in_place_type<DisplayRenderAreaBuilder>,
- Rect(), size,
- static_cast<ui::Dataspace>(args.dataspace),
- displayWeak, options),
- getLayerSnapshotsFn, size, static_cast<ui::PixelFormat>(args.pixelFormat),
- kAllowProtected, kGrayscale, captureListener);
+ ScreenshotArgs screenshotArgs;
+ screenshotArgs.captureTypeVariant = displayWeak;
+ screenshotArgs.displayId = displayId;
+ screenshotArgs.sourceCrop = layerStackSpaceRect;
+ screenshotArgs.reqSize = size;
+ screenshotArgs.dataspace = static_cast<ui::Dataspace>(args.dataspace);
+ screenshotArgs.isSecure = args.captureSecureLayers && displayIsSecure;
+ screenshotArgs.seamlessTransition = args.hintForSeamlessTransition;
+
+ captureScreenCommon(screenshotArgs, getLayerSnapshotsFn, size,
+ static_cast<ui::PixelFormat>(args.pixelFormat), kAllowProtected, kGrayscale,
+ captureListener);
}
ScreenCaptureResults SurfaceFlinger::captureLayersSync(const LayerCaptureArgs& args) {
@@ -7425,14 +7475,16 @@
return;
}
- ftl::Flags<RenderArea::Options> options;
- if (captureArgs.captureSecureLayers) options |= RenderArea::Options::CAPTURE_SECURE_LAYERS;
- if (captureArgs.hintForSeamlessTransition)
- options |= RenderArea::Options::HINT_FOR_SEAMLESS_TRANSITION;
- captureScreenCommon(RenderAreaBuilderVariant(std::in_place_type<LayerRenderAreaBuilder>, crop,
- reqSize, dataspace, parent, args.childrenOnly,
- options),
- getLayerSnapshotsFn, reqSize,
+ ScreenshotArgs screenshotArgs;
+ screenshotArgs.captureTypeVariant = parent->getSequence();
+ screenshotArgs.childrenOnly = args.childrenOnly;
+ screenshotArgs.sourceCrop = crop;
+ screenshotArgs.reqSize = reqSize;
+ screenshotArgs.dataspace = static_cast<ui::Dataspace>(captureArgs.dataspace);
+ screenshotArgs.isSecure = captureArgs.captureSecureLayers;
+ screenshotArgs.seamlessTransition = captureArgs.hintForSeamlessTransition;
+
+ captureScreenCommon(screenshotArgs, getLayerSnapshotsFn, reqSize,
static_cast<ui::PixelFormat>(captureArgs.pixelFormat),
captureArgs.allowProtected, captureArgs.grayscale, captureListener);
}
@@ -7468,10 +7520,10 @@
// is reduced when grabbed from the main thread, thus also reducing
// risk of deadlocks.
std::optional<SurfaceFlinger::OutputCompositionState> SurfaceFlinger::getSnapshotsFromMainThread(
- RenderAreaBuilderVariant& renderAreaBuilder, GetLayerSnapshotsFunction getLayerSnapshotsFn,
+ ScreenshotArgs& args, GetLayerSnapshotsFunction getLayerSnapshotsFn,
std::vector<std::pair<Layer*, sp<LayerFE>>>& layers) {
return mScheduler
- ->schedule([=, this, &renderAreaBuilder, &layers]() REQUIRES(kMainThreadContext) {
+ ->schedule([=, this, &args, &layers]() REQUIRES(kMainThreadContext) {
SFTRACE_NAME_FOR_TRACK(WorkloadTracer::TRACK_NAME, "Screenshot");
mPowerAdvisor->setScreenshotWorkload();
SFTRACE_NAME("getSnapshotsFromMainThread");
@@ -7486,12 +7538,12 @@
ui::INVALID_LAYER_STACK);
}
}
- return getDisplayStateFromRenderAreaBuilder(renderAreaBuilder);
+ return getDisplayStateOnMainThread(args);
})
.get();
}
-void SurfaceFlinger::captureScreenCommon(RenderAreaBuilderVariant renderAreaBuilder,
+void SurfaceFlinger::captureScreenCommon(ScreenshotArgs& args,
GetLayerSnapshotsFunction getLayerSnapshotsFn,
ui::Size bufferSize, ui::PixelFormat reqPixelFormat,
bool allowProtected, bool grayscale,
@@ -7507,7 +7559,11 @@
}
std::vector<std::pair<Layer*, sp<LayerFE>>> layers;
- auto displayState = getSnapshotsFromMainThread(renderAreaBuilder, getLayerSnapshotsFn, layers);
+ auto displayState = getSnapshotsFromMainThread(args, getLayerSnapshotsFn, layers);
+ if (!displayState) {
+ ALOGD("Display state not found");
+ invokeScreenCaptureError(NO_MEMORY, captureListener);
+ }
const bool hasHdrLayer = std::any_of(layers.cbegin(), layers.cend(), [this](const auto& layer) {
return isHdrLayer(*(layer.second->mSnapshot.get()));
@@ -7545,12 +7601,8 @@
std::shared_ptr<renderengine::impl::ExternalTexture> hdrTexture;
std::shared_ptr<renderengine::impl::ExternalTexture> gainmapTexture;
- bool hintForSeamless = std::visit(
- [](auto&& arg) {
- return arg.options.test(RenderArea::Options::HINT_FOR_SEAMLESS_TRANSITION);
- },
- renderAreaBuilder);
- if (hasHdrLayer && !hintForSeamless && FlagManager::getInstance().true_hdr_screenshots()) {
+ if (hasHdrLayer && !args.seamlessTransition &&
+ FlagManager::getInstance().true_hdr_screenshots()) {
const auto hdrBuffer =
getFactory().createGraphicBuffer(buffer->getWidth(), buffer->getHeight(),
HAL_PIXEL_FORMAT_RGBA_FP16, 1 /* layerCount */,
@@ -7583,35 +7635,41 @@
}
}
- auto futureFence = captureScreenshot(renderAreaBuilder, texture, false /* regionSampling */,
- grayscale, isProtected, captureListener, displayState,
- layers, hdrTexture, gainmapTexture);
+ auto futureFence =
+ captureScreenshot(args, texture, false /* regionSampling */, grayscale, isProtected,
+ captureListener, displayState, layers, hdrTexture, gainmapTexture);
futureFence.get();
}
-std::optional<SurfaceFlinger::OutputCompositionState>
-SurfaceFlinger::getDisplayStateFromRenderAreaBuilder(RenderAreaBuilderVariant& renderAreaBuilder) {
+std::optional<SurfaceFlinger::OutputCompositionState> SurfaceFlinger::getDisplayStateOnMainThread(
+ ScreenshotArgs& args) {
sp<const DisplayDevice> display = nullptr;
{
Mutex::Autolock lock(mStateLock);
- if (auto* layerRenderAreaBuilder =
- std::get_if<LayerRenderAreaBuilder>(&renderAreaBuilder)) {
+ // Screenshot initiated through captureLayers
+ if (auto* layerSequence = std::get_if<int32_t>(&args.captureTypeVariant)) {
// LayerSnapshotBuilder should only be accessed from the main thread.
const frontend::LayerSnapshot* snapshot =
- mLayerSnapshotBuilder.getSnapshot(layerRenderAreaBuilder->layer->getSequence());
+ mLayerSnapshotBuilder.getSnapshot(*layerSequence);
if (!snapshot) {
- ALOGW("Couldn't find layer snapshot for %d",
- layerRenderAreaBuilder->layer->getSequence());
+ ALOGW("Couldn't find layer snapshot for %d", *layerSequence);
} else {
- layerRenderAreaBuilder->setLayerSnapshot(*snapshot);
+ if (!args.childrenOnly) {
+ args.transform = snapshot->localTransform.inverse();
+ }
+ if (args.sourceCrop.isEmpty()) {
+ args.sourceCrop = snapshot->bufferSize;
+ }
display = findDisplay(
[layerStack = snapshot->outputFilter.layerStack](const auto& display) {
return display.getLayerStack() == layerStack;
});
}
- } else if (auto* displayRenderAreaBuilder =
- std::get_if<DisplayRenderAreaBuilder>(&renderAreaBuilder)) {
- display = displayRenderAreaBuilder->displayWeak.promote();
+
+ // Screenshot initiated through captureDisplay
+ } else if (auto* displayWeak =
+ std::get_if<wp<const DisplayDevice>>(&args.captureTypeVariant)) {
+ display = displayWeak->promote();
}
if (display == nullptr) {
@@ -7626,9 +7684,9 @@
}
ftl::SharedFuture<FenceResult> SurfaceFlinger::captureScreenshot(
- const RenderAreaBuilderVariant& renderAreaBuilder,
- const std::shared_ptr<renderengine::ExternalTexture>& buffer, bool regionSampling,
- bool grayscale, bool isProtected, const sp<IScreenCaptureListener>& captureListener,
+ const ScreenshotArgs& args, const std::shared_ptr<renderengine::ExternalTexture>& buffer,
+ bool regionSampling, bool grayscale, bool isProtected,
+ const sp<IScreenCaptureListener>& captureListener,
const std::optional<OutputCompositionState>& displayState,
const std::vector<std::pair<Layer*, sp<LayerFE>>>& layers,
const std::shared_ptr<renderengine::ExternalTexture>& hdrBuffer,
@@ -7636,18 +7694,6 @@
SFTRACE_CALL();
ScreenCaptureResults captureResults;
- std::unique_ptr<const RenderArea> renderArea =
- std::visit([](auto&& arg) -> std::unique_ptr<RenderArea> { return arg.build(); },
- renderAreaBuilder);
-
- if (!renderArea) {
- ALOGW("Skipping screen capture because of invalid render area.");
- if (captureListener) {
- captureResults.fenceResult = base::unexpected(NO_MEMORY);
- captureListener->onScreenCaptureCompleted(captureResults);
- }
- return ftl::yield<FenceResult>(base::unexpected(NO_ERROR)).share();
- }
float displayBrightnessNits = displayState.value().displayBrightnessNits;
float sdrWhitePointNits = displayState.value().sdrWhitePointNits;
@@ -7656,8 +7702,8 @@
if (hdrBuffer && gainmapBuffer) {
ftl::SharedFuture<FenceResult> hdrRenderFuture =
- renderScreenImpl(std::move(renderArea), hdrBuffer, regionSampling, grayscale,
- isProtected, captureResults, displayState, layers);
+ renderScreenImpl(args, hdrBuffer, regionSampling, grayscale, isProtected,
+ captureResults, displayState, layers);
captureResults.buffer = buffer->getBuffer();
captureResults.optionalGainMap = gainmapBuffer->getBuffer();
@@ -7680,8 +7726,8 @@
})
.share();
} else {
- renderFuture = renderScreenImpl(std::move(renderArea), buffer, regionSampling, grayscale,
- isProtected, captureResults, displayState, layers);
+ renderFuture = renderScreenImpl(args, buffer, regionSampling, grayscale, isProtected,
+ captureResults, displayState, layers);
}
if (captureListener) {
@@ -7701,8 +7747,7 @@
}
ftl::SharedFuture<FenceResult> SurfaceFlinger::renderScreenImpl(
- std::unique_ptr<const RenderArea> renderArea,
- const std::shared_ptr<renderengine::ExternalTexture>& buffer,
+ const ScreenshotArgs& args, const std::shared_ptr<renderengine::ExternalTexture>& buffer,
bool regionSampling, bool grayscale, bool isProtected, ScreenCaptureResults& captureResults,
const std::optional<OutputCompositionState>& displayState,
const std::vector<std::pair<Layer*, sp<LayerFE>>>& layers) {
@@ -7713,29 +7758,27 @@
captureResults.capturedSecureLayers |= (snapshot->isVisible && snapshot->isSecure);
captureResults.capturedHdrLayers |= isHdrLayer(*snapshot);
layerFE->mSnapshot->geomLayerTransform =
- renderArea->getTransform() * layerFE->mSnapshot->geomLayerTransform;
+ args.transform * layerFE->mSnapshot->geomLayerTransform;
layerFE->mSnapshot->geomInverseLayerTransform =
layerFE->mSnapshot->geomLayerTransform.inverse();
}
auto capturedBuffer = buffer;
- auto requestedDataspace = renderArea->getReqDataSpace();
- auto parent = renderArea->getParentLayer();
auto renderIntent = RenderIntent::TONE_MAP_COLORIMETRIC;
auto sdrWhitePointNits = DisplayDevice::sDefaultMaxLumiance;
auto displayBrightnessNits = DisplayDevice::sDefaultMaxLumiance;
- captureResults.capturedDataspace = requestedDataspace;
+ captureResults.capturedDataspace = args.dataspace;
- const bool enableLocalTonemapping = FlagManager::getInstance().local_tonemap_screenshots() &&
- !renderArea->getHintForSeamlessTransition();
+ const bool enableLocalTonemapping =
+ FlagManager::getInstance().local_tonemap_screenshots() && !args.seamlessTransition;
if (displayState) {
const auto& state = displayState.value();
captureResults.capturedDataspace =
- pickBestDataspace(requestedDataspace, state, captureResults.capturedHdrLayers,
- renderArea->getHintForSeamlessTransition());
+ pickBestDataspace(args.dataspace, state, captureResults.capturedHdrLayers,
+ args.seamlessTransition);
sdrWhitePointNits = state.sdrWhitePointNits;
if (!captureResults.capturedHdrLayers) {
@@ -7747,7 +7790,7 @@
// Otherwise for seamless transitions it's important to match the current
// display state as the buffer will be shown under these same conditions, and we
// want to avoid any flickers
- if (sdrWhitePointNits > 1.0f && !renderArea->getHintForSeamlessTransition()) {
+ if (sdrWhitePointNits > 1.0f && !args.seamlessTransition) {
// Restrict the amount of HDR "headroom" in the screenshot to avoid
// over-dimming the SDR portion. 2.0 chosen by experimentation
constexpr float kMaxScreenshotHeadroom = 2.0f;
@@ -7758,8 +7801,7 @@
}
// Screenshots leaving the device should be colorimetric
- if (requestedDataspace == ui::Dataspace::UNKNOWN &&
- renderArea->getHintForSeamlessTransition()) {
+ if (args.dataspace == ui::Dataspace::UNKNOWN && args.seamlessTransition) {
renderIntent = state.renderIntent;
}
}
@@ -7774,7 +7816,7 @@
auto present = [this, buffer = capturedBuffer, dataspace = captureResults.capturedDataspace,
sdrWhitePointNits, displayBrightnessNits, grayscale, isProtected, layers,
- layerStack, regionSampling, renderArea = std::move(renderArea), renderIntent,
+ layerStack, regionSampling, args, renderIntent,
enableLocalTonemapping]() -> FenceResult {
std::unique_ptr<compositionengine::CompositionEngine> compositionEngine =
mFactory.createCompositionEngine();
@@ -7810,23 +7852,33 @@
}
}
+ // Capturing screenshots using layers have a clear capture fill (0 alpha).
+ // Capturing via display or displayId, which do not use args.layerSequence,
+ // has an opaque capture fill (1 alpha).
+ const float layerAlpha =
+ std::holds_alternative<int32_t>(args.captureTypeVariant) ? 0.0f : 1.0f;
+
// Screenshots leaving the device must not dim in gamma space.
- const bool dimInGammaSpaceForEnhancedScreenshots = mDimInGammaSpaceForEnhancedScreenshots &&
- renderArea->getHintForSeamlessTransition();
+ const bool dimInGammaSpaceForEnhancedScreenshots =
+ mDimInGammaSpaceForEnhancedScreenshots && args.seamlessTransition;
std::shared_ptr<ScreenCaptureOutput> output = createScreenCaptureOutput(
ScreenCaptureOutputArgs{.compositionEngine = *compositionEngine,
.colorProfile = colorProfile,
- .renderArea = *renderArea,
.layerStack = layerStack,
+ .sourceCrop = args.sourceCrop,
.buffer = std::move(buffer),
+ .displayId = args.displayId,
+ .reqBufferSize = args.reqSize,
.sdrWhitePointNits = sdrWhitePointNits,
.displayBrightnessNits = displayBrightnessNits,
.targetBrightness = targetBrightness,
+ .layerAlpha = layerAlpha,
.regionSampling = regionSampling,
.treat170mAsSrgb = mTreat170mAsSrgb,
.dimInGammaSpaceForEnhancedScreenshots =
dimInGammaSpaceForEnhancedScreenshots,
+ .isSecure = args.isSecure,
.isProtected = isProtected,
.enableLocalTonemapping = enableLocalTonemapping});
@@ -8697,8 +8749,8 @@
if (status != OK) {
return binderStatusFromStatusT(status);
}
- const auto id = DisplayId::fromValue<PhysicalDisplayId>(static_cast<uint64_t>(displayId));
- *outDisplay = mFlinger->getPhysicalDisplayToken(*id);
+ const PhysicalDisplayId id = PhysicalDisplayId::fromValue(static_cast<uint64_t>(displayId));
+ *outDisplay = mFlinger->getPhysicalDisplayToken(id);
return binder::Status::ok();
}
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index b3a3aad..935a2da 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -132,7 +132,6 @@
class MessageBase;
class RefreshRateOverlay;
class RegionSamplingThread;
-class RenderArea;
class TimeStats;
class FrameTracer;
class ScreenCapturer;
@@ -197,9 +196,6 @@
Always,
};
-struct DisplayRenderAreaBuilder;
-struct LayerRenderAreaBuilder;
-
using DisplayColorSetting = compositionengine::OutputColorSetting;
class SurfaceFlinger : public BnSurfaceComposer,
@@ -371,9 +367,7 @@
friend class Layer;
friend class RefreshRateOverlay;
friend class RegionSamplingThread;
- friend class LayerRenderArea;
friend class SurfaceComposerAIDL;
- friend class DisplayRenderArea;
// For unit tests
friend class TestableSurfaceFlinger;
@@ -382,7 +376,6 @@
using TransactionSchedule = scheduler::TransactionSchedule;
using GetLayerSnapshotsFunction = std::function<std::vector<std::pair<Layer*, sp<LayerFE>>>()>;
- using RenderAreaBuilderVariant = std::variant<DisplayRenderAreaBuilder, LayerRenderAreaBuilder>;
using DumpArgs = Vector<String16>;
using Dumper = std::function<void(const DumpArgs&, bool asProto, std::string&)>;
@@ -868,20 +861,56 @@
using OutputCompositionState = compositionengine::impl::OutputCompositionState;
+ /*
+ * Parameters used across screenshot methods.
+ */
+ struct ScreenshotArgs {
+ // Contains the sequence ID of the parent layer if the screenshot is
+ // initiated though captureLayers(), or the display that the render
+ // result will be on if initiated through captureDisplay()
+ std::variant<int32_t, wp<const DisplayDevice>> captureTypeVariant;
+
+ // Display ID of the display the result will be on
+ std::optional<DisplayId> displayId{std::nullopt};
+
+ // If true, transform is inverted from the parent layer snapshot
+ bool childrenOnly{false};
+
+ // Source crop of the render area
+ Rect sourceCrop;
+
+ // Transform to be applied on the layers to transform them
+ // into the logical render area
+ ui::Transform transform;
+
+ // Size of the physical render area
+ ui::Size reqSize;
+
+ // Composition dataspace of the render area
+ ui::Dataspace dataspace;
+
+ // If false, the secure layer is blacked out or skipped
+ // when rendered to an insecure render area
+ bool isSecure{false};
+
+ // If true, the render result may be used for system animations
+ // that must preserve the exact colors of the display
+ bool seamlessTransition{false};
+ };
+
std::optional<OutputCompositionState> getSnapshotsFromMainThread(
- RenderAreaBuilderVariant& renderAreaBuilder,
- GetLayerSnapshotsFunction getLayerSnapshotsFn,
+ ScreenshotArgs& args, GetLayerSnapshotsFunction getLayerSnapshotsFn,
std::vector<std::pair<Layer*, sp<LayerFE>>>& layers);
- void captureScreenCommon(RenderAreaBuilderVariant, GetLayerSnapshotsFunction,
- ui::Size bufferSize, ui::PixelFormat, bool allowProtected,
- bool grayscale, const sp<IScreenCaptureListener>&);
+ void captureScreenCommon(ScreenshotArgs& args, GetLayerSnapshotsFunction, ui::Size bufferSize,
+ ui::PixelFormat, bool allowProtected, bool grayscale,
+ const sp<IScreenCaptureListener>&);
- std::optional<OutputCompositionState> getDisplayStateFromRenderAreaBuilder(
- RenderAreaBuilderVariant& renderAreaBuilder) REQUIRES(kMainThreadContext);
+ std::optional<OutputCompositionState> getDisplayStateOnMainThread(ScreenshotArgs& args)
+ REQUIRES(kMainThreadContext);
ftl::SharedFuture<FenceResult> captureScreenshot(
- const RenderAreaBuilderVariant& renderAreaBuilder,
+ const ScreenshotArgs& args,
const std::shared_ptr<renderengine::ExternalTexture>& buffer, bool regionSampling,
bool grayscale, bool isProtected, const sp<IScreenCaptureListener>& captureListener,
const std::optional<OutputCompositionState>& displayState,
@@ -890,8 +919,7 @@
const std::shared_ptr<renderengine::ExternalTexture>& gainmapBuffer = nullptr);
ftl::SharedFuture<FenceResult> renderScreenImpl(
- std::unique_ptr<const RenderArea> renderArea,
- const std::shared_ptr<renderengine::ExternalTexture>&,
+ const ScreenshotArgs& args, const std::shared_ptr<renderengine::ExternalTexture>&,
bool regionSampling, bool grayscale, bool isProtected, ScreenCaptureResults&,
const std::optional<OutputCompositionState>& displayState,
const std::vector<std::pair<Layer*, sp<LayerFE>>>& layers);
diff --git a/services/surfaceflinger/common/include/common/WorkloadTracer.h b/services/surfaceflinger/common/include/common/WorkloadTracer.h
index 39b6fa1..c4074f7 100644
--- a/services/surfaceflinger/common/include/common/WorkloadTracer.h
+++ b/services/surfaceflinger/common/include/common/WorkloadTracer.h
@@ -23,7 +23,7 @@
static constexpr int32_t COMPOSITION_TRACE_COOKIE = 1;
static constexpr int32_t POST_COMPOSITION_TRACE_COOKIE = 2;
-static constexpr size_t COMPOSITION_SUMMARY_SIZE = 20;
+static constexpr size_t COMPOSITION_SUMMARY_SIZE = 64;
static constexpr const char* TRACK_NAME = "CriticalWorkload";
} // namespace android::WorkloadTracer
\ No newline at end of file
diff --git a/services/surfaceflinger/tests/LayerCallback_test.cpp b/services/surfaceflinger/tests/LayerCallback_test.cpp
index b4496d3..5a82914 100644
--- a/services/surfaceflinger/tests/LayerCallback_test.cpp
+++ b/services/surfaceflinger/tests/LayerCallback_test.cpp
@@ -147,7 +147,7 @@
<< "Timeout waiting for vsync event";
DisplayEventReceiver::Event event;
while (mDisplayEventReceiver.getEvents(&event, 1) > 0) {
- if (event.header.type != DisplayEventReceiver::DISPLAY_EVENT_VSYNC) {
+ if (event.header.type != DisplayEventType::DISPLAY_EVENT_VSYNC) {
continue;
}
diff --git a/services/surfaceflinger/tests/common/LayerLifecycleManagerHelper.h b/services/surfaceflinger/tests/common/LayerLifecycleManagerHelper.h
index ee5d919..7910e77 100644
--- a/services/surfaceflinger/tests/common/LayerLifecycleManagerHelper.h
+++ b/services/surfaceflinger/tests/common/LayerLifecycleManagerHelper.h
@@ -497,17 +497,6 @@
mLifecycleManager.applyTransactions(transactions);
}
- void setClientDrawnShadowRadius(uint32_t id, float clientDrawnShadowRadius) {
- std::vector<QueuedTransactionState> transactions;
- transactions.emplace_back();
- transactions.back().states.push_back({});
-
- transactions.back().states.front().state.what = layer_state_t::eClientDrawnShadowsChanged;
- transactions.back().states.front().layerId = id;
- transactions.back().states.front().state.clientDrawnShadowRadius = clientDrawnShadowRadius;
- mLifecycleManager.applyTransactions(transactions);
- }
-
void setShadowRadius(uint32_t id, float shadowRadius) {
std::vector<QueuedTransactionState> transactions;
transactions.emplace_back();
diff --git a/services/surfaceflinger/tests/unittests/Android.bp b/services/surfaceflinger/tests/unittests/Android.bp
index 42259af..f1c1549 100644
--- a/services/surfaceflinger/tests/unittests/Android.bp
+++ b/services/surfaceflinger/tests/unittests/Android.bp
@@ -65,9 +65,9 @@
"mock/MockFrameTracer.cpp",
"mock/MockNativeWindowSurface.cpp",
"mock/MockTimeStats.cpp",
- "mock/MockVsyncController.cpp",
"mock/MockVSyncDispatch.cpp",
"mock/MockVSyncTracker.cpp",
+ "mock/MockVsyncController.cpp",
],
}
@@ -87,10 +87,10 @@
test_suites: ["device-tests"],
header_libs: ["surfaceflinger_tests_common_headers"],
srcs: [
+ "*.cpp",
":libsurfaceflinger_backend_mock_sources",
":libsurfaceflinger_mock_sources",
":libsurfaceflinger_sources",
- "*.cpp",
],
}
@@ -117,9 +117,8 @@
"android.hardware.power@1.2",
"android.hardware.power@1.3",
"libaidlcommonsupport",
- "libcompositionengine_mocks",
"libcompositionengine",
- "libframetimeline",
+ "libcompositionengine_mocks",
"libgmock",
"libgui_mocks",
"libperfetto_client_experimental",
@@ -140,14 +139,15 @@
"android.hardware.graphics.allocator@2.0",
"android.hardware.graphics.allocator@3.0",
"android.hardware.graphics.common@1.2",
+ "libEGL",
+ "libGLESv1_CM",
+ "libGLESv2",
+ "libSurfaceFlingerProp",
"libbase",
"libbinder",
"libbinder_ndk",
"libcutils",
- "libEGL",
"libfmq",
- "libGLESv1_CM",
- "libGLESv2",
"libgui",
"libhidlbase",
"libinput",
@@ -157,11 +157,10 @@
"libprocessgroup",
"libprotobuf-cpp-lite",
"libstatslog_surfaceflinger",
- "libSurfaceFlingerProp",
"libsync",
+ "libtracing_perfetto",
"libui",
"libutils",
- "libtracing_perfetto",
],
header_libs: [
"android.hardware.graphics.composer3-command-buffer",
diff --git a/services/surfaceflinger/tests/unittests/CompositionTest.cpp b/services/surfaceflinger/tests/unittests/CompositionTest.cpp
index 71cafbf..9ece312 100644
--- a/services/surfaceflinger/tests/unittests/CompositionTest.cpp
+++ b/services/surfaceflinger/tests/unittests/CompositionTest.cpp
@@ -36,7 +36,6 @@
#include <system/window.h>
#include <utils/String8.h>
-#include "DisplayRenderArea.h"
#include "Layer.h"
#include "TestableSurfaceFlinger.h"
#include "mock/DisplayHardware/MockComposer.h"
@@ -199,25 +198,21 @@
const Rect sourceCrop(0, 0, DEFAULT_DISPLAY_WIDTH, DEFAULT_DISPLAY_HEIGHT);
constexpr bool regionSampling = false;
- auto renderArea =
- DisplayRenderArea::create(mDisplay, sourceCrop, sourceCrop.getSize(),
- ui::Dataspace::V0_SRGB,
- RenderArea::Options::CAPTURE_SECURE_LAYERS |
- RenderArea::Options::HINT_FOR_SEAMLESS_TRANSITION);
-
auto getLayerSnapshotsFn = mFlinger.getLayerSnapshotsForScreenshotsFn(mDisplay->getLayerStack(),
CaptureArgs::UNSET_UID);
const uint32_t usage = GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN |
GRALLOC_USAGE_HW_RENDER | GRALLOC_USAGE_HW_TEXTURE;
mCaptureScreenBuffer =
- std::make_shared<renderengine::mock::FakeExternalTexture>(renderArea->getReqWidth(),
- renderArea->getReqHeight(),
+ std::make_shared<renderengine::mock::FakeExternalTexture>(sourceCrop.getSize().width,
+ sourceCrop.getSize().height,
HAL_PIXEL_FORMAT_RGBA_8888, 1,
usage);
- auto future = mFlinger.renderScreenImpl(mDisplay, std::move(renderArea), getLayerSnapshotsFn,
- mCaptureScreenBuffer, regionSampling);
+ auto future = mFlinger.renderScreenImpl(mDisplay, sourceCrop, ui::Dataspace::V0_SRGB,
+ getLayerSnapshotsFn, mCaptureScreenBuffer,
+ regionSampling, mDisplay->isSecure(),
+ /* seamlessTransition */ true);
ASSERT_TRUE(future.valid());
const auto fenceResult = future.get();
diff --git a/services/surfaceflinger/tests/unittests/DisplayTransactionTestHelpers.h b/services/surfaceflinger/tests/unittests/DisplayTransactionTestHelpers.h
index 3fead93..81bfc97 100644
--- a/services/surfaceflinger/tests/unittests/DisplayTransactionTestHelpers.h
+++ b/services/surfaceflinger/tests/unittests/DisplayTransactionTestHelpers.h
@@ -193,7 +193,7 @@
}
};
-template <uint64_t displayId>
+template <VirtualDisplayId::BaseId displayId>
struct DisplayIdGetter<HalVirtualDisplayIdType<displayId>> {
static HalVirtualDisplayId get() { return HalVirtualDisplayId(displayId); }
};
diff --git a/services/surfaceflinger/tests/unittests/EventThreadTest.cpp b/services/surfaceflinger/tests/unittests/EventThreadTest.cpp
index 268a6c4..6f15db8 100644
--- a/services/surfaceflinger/tests/unittests/EventThreadTest.cpp
+++ b/services/surfaceflinger/tests/unittests/EventThreadTest.cpp
@@ -30,7 +30,7 @@
#include "AsyncCallRecorder.h"
#include "DisplayHardware/DisplayMode.h"
-#include "FrameTimeline.h"
+#include "FrameTimeline/FrameTimeline.h"
#include "Scheduler/EventThread.h"
#include "mock/MockVSyncDispatch.h"
#include "mock/MockVSyncTracker.h"
@@ -270,7 +270,7 @@
ASSERT_TRUE(args.has_value()) << name << " did not receive an event for timestamp "
<< expectedTimestamp;
const auto& event = std::get<0>(args.value());
- EXPECT_EQ(DisplayEventReceiver::DISPLAY_EVENT_VSYNC, event.header.type)
+ EXPECT_EQ(DisplayEventType::DISPLAY_EVENT_VSYNC, event.header.type)
<< name << " did not get the correct event for timestamp " << expectedTimestamp;
EXPECT_EQ(expectedTimestamp, event.header.timestamp)
<< name << " did not get the expected timestamp for timestamp " << expectedTimestamp;
@@ -344,7 +344,7 @@
auto args = mConnectionEventCallRecorder.waitForCall();
ASSERT_TRUE(args.has_value());
const auto& event = std::get<0>(args.value());
- EXPECT_EQ(DisplayEventReceiver::DISPLAY_EVENT_HOTPLUG, event.header.type);
+ EXPECT_EQ(DisplayEventType::DISPLAY_EVENT_HOTPLUG, event.header.type);
EXPECT_EQ(expectedDisplayId, event.header.displayId);
EXPECT_EQ(expectedConnected, event.hotplug.connected);
}
@@ -355,7 +355,7 @@
auto args = mConnectionEventCallRecorder.waitForCall();
ASSERT_TRUE(args.has_value());
const auto& event = std::get<0>(args.value());
- EXPECT_EQ(DisplayEventReceiver::DISPLAY_EVENT_MODE_CHANGE, event.header.type);
+ EXPECT_EQ(DisplayEventType::DISPLAY_EVENT_MODE_CHANGE, event.header.type);
EXPECT_EQ(expectedDisplayId, event.header.displayId);
EXPECT_EQ(expectedConfigId, event.modeChange.modeId);
EXPECT_EQ(expectedVsyncPeriod, event.modeChange.vsyncPeriod);
@@ -367,7 +367,7 @@
auto args = mConnectionEventCallRecorder.waitForCall();
ASSERT_TRUE(args.has_value());
const auto& event = std::get<0>(args.value());
- EXPECT_EQ(DisplayEventReceiver::DISPLAY_EVENT_FRAME_RATE_OVERRIDE, event.header.type);
+ EXPECT_EQ(DisplayEventType::DISPLAY_EVENT_FRAME_RATE_OVERRIDE, event.header.type);
EXPECT_EQ(expectedDisplayId, event.header.displayId);
EXPECT_EQ(uid, event.frameRateOverride.uid);
EXPECT_EQ(frameRateHz, event.frameRateOverride.frameRateHz);
@@ -376,7 +376,7 @@
auto args = mConnectionEventCallRecorder.waitForCall();
ASSERT_TRUE(args.has_value());
const auto& event = std::get<0>(args.value());
- EXPECT_EQ(DisplayEventReceiver::DISPLAY_EVENT_FRAME_RATE_OVERRIDE_FLUSH, event.header.type);
+ EXPECT_EQ(DisplayEventType::DISPLAY_EVENT_FRAME_RATE_OVERRIDE_FLUSH, event.header.type);
EXPECT_EQ(expectedDisplayId, event.header.displayId);
}
@@ -874,7 +874,7 @@
auto args = mConnectionEventCallRecorder.waitForCall();
ASSERT_TRUE(args.has_value());
const auto& event = std::get<0>(args.value());
- EXPECT_EQ(DisplayEventReceiver::DISPLAY_EVENT_HDCP_LEVELS_CHANGE, event.header.type);
+ EXPECT_EQ(DisplayEventType::DISPLAY_EVENT_HDCP_LEVELS_CHANGE, event.header.type);
EXPECT_EQ(EXTERNAL_DISPLAY_ID, event.header.displayId);
EXPECT_EQ(HDCP_V1, event.hdcpLevelsChange.connectedLevel);
EXPECT_EQ(HDCP_V2, event.hdcpLevelsChange.maxLevel);
diff --git a/services/surfaceflinger/tests/unittests/JankTrackerTest.cpp b/services/surfaceflinger/tests/unittests/JankTrackerTest.cpp
index 2941a14..0f16073 100644
--- a/services/surfaceflinger/tests/unittests/JankTrackerTest.cpp
+++ b/services/surfaceflinger/tests/unittests/JankTrackerTest.cpp
@@ -213,4 +213,33 @@
EXPECT_EQ(listenerCount(), 0u);
}
-} // namespace android
\ No newline at end of file
+TEST_F(JankTrackerTest, multipleLayersAreTrackedIndependently) {
+ size_t jankDataReceived = 0;
+ size_t numBatchesReceived = 0;
+
+ EXPECT_CALL(*mListener.get(), onJankData(_))
+ .WillRepeatedly([&](const std::vector<gui::JankData>& jankData) {
+ jankDataReceived += jankData.size();
+ numBatchesReceived++;
+ return binder::Status::ok();
+ });
+ addJankListener(123);
+ addJankListener(321);
+ addJankData(123, 1);
+ addJankData(123, 2);
+ addJankData(123, 3);
+ addJankData(321, 4);
+ addJankData(321, 5);
+
+ JankTracker::flushJankData(123);
+ flushBackgroundThread();
+ EXPECT_EQ(numBatchesReceived, 1u);
+ EXPECT_EQ(jankDataReceived, 3u);
+
+ JankTracker::flushJankData(321);
+ flushBackgroundThread();
+ EXPECT_EQ(numBatchesReceived, 2u);
+ EXPECT_EQ(jankDataReceived, 5u);
+}
+
+} // namespace android
diff --git a/services/surfaceflinger/tests/unittests/LayerSnapshotTest.cpp b/services/surfaceflinger/tests/unittests/LayerSnapshotTest.cpp
index 453c053..7aad84b 100644
--- a/services/surfaceflinger/tests/unittests/LayerSnapshotTest.cpp
+++ b/services/surfaceflinger/tests/unittests/LayerSnapshotTest.cpp
@@ -1505,14 +1505,6 @@
EXPECT_EQ(getSnapshot({.id = 111})->roundedCorner.radius.x, RADIUS);
}
-TEST_F(LayerSnapshotTest, ignoreShadows) {
- static constexpr float SHADOW_RADIUS = 123.f;
- setClientDrawnShadowRadius(1, SHADOW_RADIUS);
- setShadowRadius(1, SHADOW_RADIUS);
- UPDATE_AND_VERIFY(mSnapshotBuilder, STARTING_ZORDER);
- EXPECT_EQ(getSnapshot({.id = 1})->shadowSettings.length, 0.f);
-}
-
TEST_F(LayerSnapshotTest, setShadowRadius) {
static constexpr float SHADOW_RADIUS = 123.f;
setShadowRadius(1, SHADOW_RADIUS);
diff --git a/services/surfaceflinger/tests/unittests/MessageQueueTest.cpp b/services/surfaceflinger/tests/unittests/MessageQueueTest.cpp
index 908637a..e9b86b2 100644
--- a/services/surfaceflinger/tests/unittests/MessageQueueTest.cpp
+++ b/services/surfaceflinger/tests/unittests/MessageQueueTest.cpp
@@ -22,7 +22,7 @@
#include <scheduler/interface/ICompositor.h>
-#include "FrameTimeline.h"
+#include "FrameTimeline/FrameTimeline.h"
#include "Scheduler/MessageQueue.h"
#include "mock/MockVSyncDispatch.h"
#include "utils/Timers.h"
diff --git a/services/surfaceflinger/tests/unittests/SurfaceFlinger_CreateDisplayTest.cpp b/services/surfaceflinger/tests/unittests/SurfaceFlinger_CreateDisplayTest.cpp
index 2d3ebb4..aadff76 100644
--- a/services/surfaceflinger/tests/unittests/SurfaceFlinger_CreateDisplayTest.cpp
+++ b/services/surfaceflinger/tests/unittests/SurfaceFlinger_CreateDisplayTest.cpp
@@ -27,7 +27,8 @@
class CreateDisplayTest : public DisplayTransactionTest {
public:
- void createDisplayWithRequestedRefreshRate(const std::string& name, uint64_t displayId,
+ void createDisplayWithRequestedRefreshRate(const std::string& name,
+ VirtualDisplayId::BaseId baseId,
float pacesetterDisplayRefreshRate,
float requestedRefreshRate,
float expectedAdjustedRefreshRate) {
@@ -49,12 +50,10 @@
EXPECT_EQ(display.requestedRefreshRate, Fps::fromValue(requestedRefreshRate));
EXPECT_EQ(name.c_str(), display.displayName);
- std::optional<VirtualDisplayId> vid =
- DisplayId::fromValue<VirtualDisplayId>(displayId | DisplayId::FLAG_VIRTUAL);
- ASSERT_TRUE(vid.has_value());
-
+ const VirtualDisplayId vid = GpuVirtualDisplayId(baseId);
sp<DisplayDevice> device =
- mFlinger.createVirtualDisplayDevice(displayToken, *vid, requestedRefreshRate);
+ mFlinger.createVirtualDisplayDevice(displayToken, vid, requestedRefreshRate);
+
EXPECT_TRUE(device->isVirtual());
device->adjustRefreshRate(Fps::fromValue(pacesetterDisplayRefreshRate));
// verifying desired value
diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
index 2353ef8..9a2e254 100644
--- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
+++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
@@ -42,7 +42,6 @@
#include "FrontEnd/RequestedLayerState.h"
#include "Layer.h"
#include "NativeWindowSurface.h"
-#include "RenderArea.h"
#include "Scheduler/RefreshRateSelector.h"
#include "Scheduler/VSyncTracker.h"
#include "Scheduler/VsyncController.h"
@@ -461,11 +460,11 @@
return mFlinger->setPowerModeInternal(display, mode);
}
- auto renderScreenImpl(const sp<DisplayDevice> display,
- std::unique_ptr<const RenderArea> renderArea,
+ auto renderScreenImpl(const sp<DisplayDevice> display, const Rect sourceCrop,
+ ui::Dataspace dataspace,
SurfaceFlinger::GetLayerSnapshotsFunction getLayerSnapshotsFn,
const std::shared_ptr<renderengine::ExternalTexture>& buffer,
- bool regionSampling) {
+ bool regionSampling, bool isSecure, bool seamlessTransition) {
Mutex::Autolock lock(mFlinger->mStateLock);
ftl::FakeGuard guard(kMainThreadContext);
@@ -473,7 +472,16 @@
auto displayState = std::optional{display->getCompositionDisplay()->getState()};
auto layers = getLayerSnapshotsFn();
- return mFlinger->renderScreenImpl(std::move(renderArea), buffer, regionSampling,
+ SurfaceFlinger::ScreenshotArgs screenshotArgs;
+ screenshotArgs.captureTypeVariant = display;
+ screenshotArgs.displayId = std::nullopt;
+ screenshotArgs.sourceCrop = sourceCrop;
+ screenshotArgs.reqSize = sourceCrop.getSize();
+ screenshotArgs.dataspace = dataspace;
+ screenshotArgs.isSecure = isSecure;
+ screenshotArgs.seamlessTransition = seamlessTransition;
+
+ return mFlinger->renderScreenImpl(screenshotArgs, buffer, regionSampling,
false /* grayscale */, false /* isProtected */,
captureResults, displayState, layers);
}
diff --git a/services/surfaceflinger/tests/vsync/vsync.cpp b/services/surfaceflinger/tests/vsync/vsync.cpp
index 8b4a6be..77a68d9 100644
--- a/services/surfaceflinger/tests/vsync/vsync.cpp
+++ b/services/surfaceflinger/tests/vsync/vsync.cpp
@@ -41,7 +41,7 @@
while ((n = q->getEvents(buffer, 1)) > 0) {
for (int i=0 ; i<n ; i++) {
- if (buffer[i].header.type == DisplayEventReceiver::DISPLAY_EVENT_VSYNC) {
+ if (buffer[i].header.type == DisplayEventType::DISPLAY_EVENT_VSYNC) {
printf("event vsync: count=%d\t", buffer[i].vsync.count);
}
if (oldTimeStamp) {