TransactionTracing: Introduce FlingerDataMapper
Allow the proto parser to handle dependencies
that are external to layer via a clear interface.
This is needed to make sure the parser can map
handles to ids, get buffer info from cached buffers
or inject fake buffers in transactions to recreate
the layer's internal state.
Test: presubmit
Bug: 200284593
Change-Id: I830048a560945cce088d7276e764c953f408e0d3
diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp
index eec4a87..9022e7d 100644
--- a/libs/gui/LayerState.cpp
+++ b/libs/gui/LayerState.cpp
@@ -35,7 +35,9 @@
using gui::WindowInfoHandle;
layer_state_t::layer_state_t()
- : what(0),
+ : surface(nullptr),
+ layerId(-1),
+ what(0),
x(0),
y(0),
z(0),
@@ -153,8 +155,12 @@
SAFE_PARCEL(output.writeBool, isTrustedOverlay);
SAFE_PARCEL(output.writeUint32, static_cast<uint32_t>(dropInputMode));
- SAFE_PARCEL(output.writeNullableParcelable,
- bufferData ? std::make_optional<BufferData>(*bufferData) : std::nullopt);
+
+ const bool hasBufferData = (bufferData != nullptr);
+ SAFE_PARCEL(output.writeBool, hasBufferData);
+ if (hasBufferData) {
+ SAFE_PARCEL(output.writeParcelable, *bufferData);
+ }
return NO_ERROR;
}
@@ -264,9 +270,15 @@
uint32_t mode;
SAFE_PARCEL(input.readUint32, &mode);
dropInputMode = static_cast<gui::DropInputMode>(mode);
- std::optional<BufferData> tmpBufferData;
- SAFE_PARCEL(input.readParcelable, &tmpBufferData);
- bufferData = tmpBufferData ? std::make_shared<BufferData>(*tmpBufferData) : nullptr;
+
+ bool hasBufferData;
+ SAFE_PARCEL(input.readBool, &hasBufferData);
+ if (hasBufferData) {
+ bufferData = std::make_shared<BufferData>();
+ SAFE_PARCEL(input.readParcelable, bufferData.get());
+ } else {
+ bufferData = nullptr;
+ }
return NO_ERROR;
}
diff --git a/services/surfaceflinger/Tracing/TransactionProtoParser.cpp b/services/surfaceflinger/Tracing/TransactionProtoParser.cpp
index a91698f..fb5a6b3 100644
--- a/services/surfaceflinger/Tracing/TransactionProtoParser.cpp
+++ b/services/surfaceflinger/Tracing/TransactionProtoParser.cpp
@@ -22,9 +22,7 @@
namespace android::surfaceflinger {
-proto::TransactionState TransactionProtoParser::toProto(const TransactionState& t,
- LayerHandleToIdFn getLayerId,
- DisplayHandleToIdFn getDisplayId) {
+proto::TransactionState TransactionProtoParser::toProto(const TransactionState& t) {
proto::TransactionState proto;
proto.set_pid(t.originPid);
proto.set_uid(t.originUid);
@@ -33,12 +31,14 @@
proto.set_post_time(t.postTime);
proto.set_transaction_id(t.id);
+ proto.mutable_layer_changes()->Reserve(static_cast<int32_t>(t.states.size()));
for (auto& layerState : t.states) {
- proto.mutable_layer_changes()->Add(std::move(toProto(layerState.state, getLayerId)));
+ proto.mutable_layer_changes()->Add(std::move(toProto(layerState.state)));
}
+ proto.mutable_display_changes()->Reserve(static_cast<int32_t>(t.displays.size()));
for (auto& displayState : t.displays) {
- proto.mutable_display_changes()->Add(std::move(toProto(displayState, getDisplayId)));
+ proto.mutable_display_changes()->Add(std::move(toProto(displayState)));
}
return proto;
}
@@ -46,8 +46,9 @@
proto::TransactionState TransactionProtoParser::toProto(
const std::map<int32_t /* layerId */, TracingLayerState>& states) {
proto::TransactionState proto;
+ proto.mutable_layer_changes()->Reserve(static_cast<int32_t>(states.size()));
for (auto& [layerId, state] : states) {
- proto::LayerState layerProto = toProto(state, nullptr);
+ proto::LayerState layerProto = toProto(state);
if (layerProto.has_buffer_data()) {
proto::LayerState_BufferData* bufferProto = layerProto.mutable_buffer_data();
bufferProto->set_buffer_id(state.bufferId);
@@ -69,11 +70,10 @@
return proto;
}
-proto::LayerState TransactionProtoParser::toProto(const layer_state_t& layer,
- LayerHandleToIdFn getLayerId) {
+proto::LayerState TransactionProtoParser::toProto(const layer_state_t& layer) {
proto::LayerState proto;
- if (getLayerId != nullptr) {
- proto.set_layer_id(getLayerId(layer.surface));
+ if (layer.surface) {
+ proto.set_layer_id(mMapper->getLayerId(layer.surface));
} else {
proto.set_layer_id(layer.layerId);
}
@@ -136,13 +136,27 @@
}
if (layer.what & layer_state_t::eBufferChanged) {
proto::LayerState_BufferData* bufferProto = proto.mutable_buffer_data();
- if (layer.bufferData->buffer) {
+ if (layer.bufferData->hasBuffer()) {
bufferProto->set_buffer_id(layer.bufferData->getId());
bufferProto->set_width(layer.bufferData->getWidth());
bufferProto->set_height(layer.bufferData->getHeight());
bufferProto->set_pixel_format(static_cast<proto::LayerState_BufferData_PixelFormat>(
layer.bufferData->getPixelFormat()));
bufferProto->set_usage(layer.bufferData->getUsage());
+ } else {
+ uint64_t bufferId;
+ uint32_t width;
+ uint32_t height;
+ int32_t pixelFormat;
+ uint64_t usage;
+ mMapper->getGraphicBufferPropertiesFromCache(layer.bufferData->cachedBuffer, &bufferId,
+ &width, &height, &pixelFormat, &usage);
+ bufferProto->set_buffer_id(bufferId);
+ bufferProto->set_width(width);
+ bufferProto->set_height(height);
+ bufferProto->set_pixel_format(
+ static_cast<proto::LayerState_BufferData_PixelFormat>(pixelFormat));
+ bufferProto->set_usage(usage);
}
bufferProto->set_frame_number(layer.bufferData->frameNumber);
bufferProto->set_flags(layer.bufferData->flags.get());
@@ -165,15 +179,15 @@
}
}
- if ((layer.what & layer_state_t::eReparent) && getLayerId != nullptr) {
+ if (layer.what & layer_state_t::eReparent) {
int32_t layerId = layer.parentSurfaceControlForChild
- ? getLayerId(layer.parentSurfaceControlForChild->getHandle())
+ ? mMapper->getLayerId(layer.parentSurfaceControlForChild->getHandle())
: -1;
proto.set_parent_id(layerId);
}
- if ((layer.what & layer_state_t::eRelativeLayerChanged) && getLayerId != nullptr) {
+ if (layer.what & layer_state_t::eRelativeLayerChanged) {
int32_t layerId = layer.relativeLayerSurfaceControl
- ? getLayerId(layer.relativeLayerSurfaceControl->getHandle())
+ ? mMapper->getLayerId(layer.relativeLayerSurfaceControl->getHandle())
: -1;
proto.set_relative_parent_id(layerId);
proto.set_z(layer.z);
@@ -200,12 +214,8 @@
transformProto->set_ty(inputInfo->transform.ty());
windowInfoProto->set_replace_touchable_region_with_crop(
inputInfo->replaceTouchableRegionWithCrop);
- if (getLayerId != nullptr) {
- windowInfoProto->set_crop_layer_id(
- getLayerId(inputInfo->touchableRegionCropHandle.promote()));
- } else {
- windowInfoProto->set_crop_layer_id(-1);
- }
+ windowInfoProto->set_crop_layer_id(
+ mMapper->getLayerId(inputInfo->touchableRegionCropHandle.promote()));
}
}
if (layer.what & layer_state_t::eBackgroundColorChanged) {
@@ -252,13 +262,10 @@
return proto;
}
-proto::DisplayState TransactionProtoParser::toProto(const DisplayState& display,
- DisplayHandleToIdFn getDisplayId) {
+proto::DisplayState TransactionProtoParser::toProto(const DisplayState& display) {
proto::DisplayState proto;
proto.set_what(display.what);
- if (getDisplayId != nullptr) {
- proto.set_id(getDisplayId(display.token));
- }
+ proto.set_id(mMapper->getDisplayId(display.token));
if (display.what & DisplayState::eLayerStackChanged) {
proto.set_layer_stack(display.layerStack.id);
@@ -290,9 +297,7 @@
return proto;
}
-TransactionState TransactionProtoParser::fromProto(const proto::TransactionState& proto,
- LayerIdToHandleFn getLayerHandle,
- DisplayIdToHandleFn getDisplayHandle) {
+TransactionState TransactionProtoParser::fromProto(const proto::TransactionState& proto) {
TransactionState t;
t.originPid = proto.pid();
t.originUid = proto.uid();
@@ -306,14 +311,14 @@
for (int i = 0; i < layerCount; i++) {
ComposerState s;
s.state.what = 0;
- fromProto(proto.layer_changes(i), getLayerHandle, s.state);
+ fromProto(proto.layer_changes(i), s.state);
t.states.add(s);
}
int32_t displayCount = proto.display_changes_size();
t.displays.reserve(static_cast<size_t>(displayCount));
for (int i = 0; i < displayCount; i++) {
- t.displays.add(fromProto(proto.display_changes(i), getDisplayHandle));
+ t.displays.add(fromProto(proto.display_changes(i)));
}
return t;
}
@@ -328,10 +333,9 @@
}
void TransactionProtoParser::mergeFromProto(const proto::LayerState& proto,
- LayerIdToHandleFn getLayerHandle,
TracingLayerState& outState) {
layer_state_t state;
- fromProto(proto, getLayerHandle, state);
+ fromProto(proto, state);
outState.merge(state);
if (state.what & layer_state_t::eReparent) {
@@ -356,14 +360,10 @@
}
}
-void TransactionProtoParser::fromProto(const proto::LayerState& proto,
- LayerIdToHandleFn getLayerHandle, layer_state_t& layer) {
+void TransactionProtoParser::fromProto(const proto::LayerState& proto, layer_state_t& layer) {
layer.layerId = proto.layer_id();
layer.what |= proto.what();
-
- if (getLayerHandle != nullptr) {
- layer.surface = getLayerHandle(layer.layerId);
- }
+ layer.surface = mMapper->getLayerHandle(layer.layerId);
if (proto.what() & layer_state_t::ePositionChanged) {
layer.x = proto.x();
@@ -420,10 +420,11 @@
LayerProtoHelper::readFromProto(proto.crop(), layer.crop);
}
if (proto.what() & layer_state_t::eBufferChanged) {
- if (!layer.bufferData) {
- layer.bufferData = std::make_shared<BufferData>();
- }
const proto::LayerState_BufferData& bufferProto = proto.buffer_data();
+ layer.bufferData =
+ std::move(mMapper->getGraphicData(bufferProto.buffer_id(), bufferProto.width(),
+ bufferProto.height(), bufferProto.pixel_format(),
+ bufferProto.usage()));
layer.bufferData->frameNumber = bufferProto.frame_number();
layer.bufferData->flags = Flags<BufferData::BufferDataChange>(bufferProto.flags());
layer.bufferData->cachedBuffer.id = bufferProto.cached_buffer_id();
@@ -445,24 +446,24 @@
}
}
- if ((proto.what() & layer_state_t::eReparent) && (getLayerHandle != nullptr)) {
+ if (proto.what() & layer_state_t::eReparent) {
int32_t layerId = proto.parent_id();
if (layerId == -1) {
layer.parentSurfaceControlForChild = nullptr;
} else {
layer.parentSurfaceControlForChild =
- new SurfaceControl(SurfaceComposerClient::getDefault(), getLayerHandle(layerId),
- nullptr, layerId);
+ new SurfaceControl(SurfaceComposerClient::getDefault(),
+ mMapper->getLayerHandle(layerId), nullptr, layerId);
}
}
if (proto.what() & layer_state_t::eRelativeLayerChanged) {
int32_t layerId = proto.relative_parent_id();
if (layerId == -1) {
layer.relativeLayerSurfaceControl = nullptr;
- } else if (getLayerHandle != nullptr) {
+ } else {
layer.relativeLayerSurfaceControl =
- new SurfaceControl(SurfaceComposerClient::getDefault(), getLayerHandle(layerId),
- nullptr, layerId);
+ new SurfaceControl(SurfaceComposerClient::getDefault(),
+ mMapper->getLayerHandle(layerId), nullptr, layerId);
}
layer.z = proto.z();
}
@@ -486,9 +487,7 @@
inputInfo.replaceTouchableRegionWithCrop =
windowInfoProto.replace_touchable_region_with_crop();
int32_t layerId = windowInfoProto.crop_layer_id();
- if (getLayerHandle != nullptr) {
- inputInfo.touchableRegionCropHandle = getLayerHandle(layerId);
- }
+ inputInfo.touchableRegionCropHandle = mMapper->getLayerHandle(layerId);
layer.windowInfoHandle = sp<gui::WindowInfoHandle>::make(inputInfo);
}
if (proto.what() & layer_state_t::eBackgroundColorChanged) {
@@ -534,13 +533,10 @@
}
}
-DisplayState TransactionProtoParser::fromProto(const proto::DisplayState& proto,
- DisplayIdToHandleFn getDisplayHandle) {
+DisplayState TransactionProtoParser::fromProto(const proto::DisplayState& proto) {
DisplayState display;
display.what = proto.what();
- if (getDisplayHandle != nullptr) {
- display.token = getDisplayHandle(proto.id());
- }
+ display.token = mMapper->getDisplayHandle(proto.id());
if (display.what & DisplayState::eLayerStackChanged) {
display.layerStack.id = proto.layer_stack();
diff --git a/services/surfaceflinger/Tracing/TransactionProtoParser.h b/services/surfaceflinger/Tracing/TransactionProtoParser.h
index d589936..2f70b27 100644
--- a/services/surfaceflinger/Tracing/TransactionProtoParser.h
+++ b/services/surfaceflinger/Tracing/TransactionProtoParser.h
@@ -43,33 +43,77 @@
TracingLayerCreationArgs args;
};
-class TransactionProtoParser {
+// Class which exposes buffer properties from BufferData without holding on to the actual buffer
+// handle.
+class BufferDataStub : public BufferData {
public:
- typedef std::function<sp<IBinder>(int32_t)> LayerIdToHandleFn;
- typedef std::function<sp<IBinder>(int32_t)> DisplayIdToHandleFn;
- typedef std::function<int32_t(const sp<IBinder>&)> LayerHandleToIdFn;
- typedef std::function<int32_t(const sp<IBinder>&)> DisplayHandleToIdFn;
-
- static proto::TransactionState toProto(const TransactionState&, LayerHandleToIdFn getLayerIdFn,
- DisplayHandleToIdFn getDisplayIdFn);
- static proto::TransactionState toProto(
- const std::map<int32_t /* layerId */, TracingLayerState>&);
-
- static proto::LayerCreationArgs toProto(const TracingLayerCreationArgs& args);
-
- static TransactionState fromProto(const proto::TransactionState&,
- LayerIdToHandleFn getLayerHandleFn,
- DisplayIdToHandleFn getDisplayHandleFn);
- static void mergeFromProto(const proto::LayerState&, LayerIdToHandleFn getLayerHandleFn,
- TracingLayerState& outState);
- static void fromProto(const proto::LayerCreationArgs&, TracingLayerCreationArgs& outArgs);
+ BufferDataStub(uint64_t bufferId, uint32_t width, uint32_t height, int32_t pixelFormat,
+ uint64_t outUsage)
+ : mBufferId(bufferId),
+ mWidth(width),
+ mHeight(height),
+ mPixelFormat(pixelFormat),
+ mOutUsage(outUsage) {}
+ bool hasBuffer() const override { return mBufferId != 0; }
+ bool hasSameBuffer(const BufferData& other) const override {
+ return getId() == other.getId() && frameNumber == other.frameNumber;
+ }
+ uint32_t getWidth() const override { return mWidth; }
+ uint32_t getHeight() const override { return mHeight; }
+ uint64_t getId() const override { return mBufferId; }
+ PixelFormat getPixelFormat() const override { return mPixelFormat; }
+ uint64_t getUsage() const override { return mOutUsage; }
private:
- static proto::LayerState toProto(const layer_state_t&, LayerHandleToIdFn getLayerId);
- static proto::DisplayState toProto(const DisplayState&, DisplayHandleToIdFn getDisplayId);
- static void fromProto(const proto::LayerState&, LayerIdToHandleFn getLayerHandle,
- layer_state_t& out);
- static DisplayState fromProto(const proto::DisplayState&, DisplayIdToHandleFn getDisplayHandle);
+ uint64_t mBufferId;
+ uint32_t mWidth;
+ uint32_t mHeight;
+ int32_t mPixelFormat;
+ uint64_t mOutUsage;
+};
+
+class TransactionProtoParser {
+public:
+ // Utility class to map handles to ids and buffers to buffer properties without pulling
+ // in SurfaceFlinger dependencies.
+ class FlingerDataMapper {
+ public:
+ virtual ~FlingerDataMapper() = default;
+ virtual sp<IBinder> getLayerHandle(int32_t /* layerId */) const { return nullptr; }
+ virtual int32_t getLayerId(const sp<IBinder>& /* layerHandle */) const { return -1; }
+ virtual sp<IBinder> getDisplayHandle(int32_t /* displayId */) const { return nullptr; }
+ virtual int32_t getDisplayId(const sp<IBinder>& /* displayHandle */) const { return -1; }
+ virtual std::shared_ptr<BufferData> getGraphicData(uint64_t bufferId, uint32_t width,
+ uint32_t height, int32_t pixelFormat,
+ uint64_t usage) const {
+ return std::make_shared<BufferDataStub>(bufferId, width, height, pixelFormat, usage);
+ }
+ virtual void getGraphicBufferPropertiesFromCache(client_cache_t /* cachedBuffer */,
+ uint64_t* /* outBufferId */,
+ uint32_t* /* outWidth */,
+ uint32_t* /* outHeight */,
+ int32_t* /* outPixelFormat */,
+ uint64_t* /* outUsage */) const {}
+ };
+
+ TransactionProtoParser(std::unique_ptr<FlingerDataMapper> provider)
+ : mMapper(std::move(provider)) {}
+
+ proto::TransactionState toProto(const TransactionState&);
+ proto::TransactionState toProto(const std::map<int32_t /* layerId */, TracingLayerState>&);
+ proto::LayerCreationArgs toProto(const TracingLayerCreationArgs& args);
+
+ TransactionState fromProto(const proto::TransactionState&);
+ void mergeFromProto(const proto::LayerState&, TracingLayerState& outState);
+ void fromProto(const proto::LayerCreationArgs&, TracingLayerCreationArgs& outArgs);
+
+private:
+ proto::LayerState toProto(const layer_state_t&);
+ proto::DisplayState toProto(const DisplayState&);
+ void fromProto(const proto::LayerState&, layer_state_t& out);
+ DisplayState fromProto(const proto::DisplayState&);
+
+ std::unique_ptr<FlingerDataMapper> mMapper;
};
} // namespace android::surfaceflinger
diff --git a/services/surfaceflinger/Tracing/TransactionTracing.cpp b/services/surfaceflinger/Tracing/TransactionTracing.cpp
index a46b795..298e63a 100644
--- a/services/surfaceflinger/Tracing/TransactionTracing.cpp
+++ b/services/surfaceflinger/Tracing/TransactionTracing.cpp
@@ -23,11 +23,57 @@
#include <utils/SystemClock.h>
#include <utils/Trace.h>
+#include "ClientCache.h"
#include "TransactionTracing.h"
+#include "renderengine/ExternalTexture.h"
namespace android {
-TransactionTracing::TransactionTracing() {
+class FlingerDataMapper : public TransactionProtoParser::FlingerDataMapper {
+ std::unordered_map<BBinder* /* layerHandle */, int32_t /* layerId */>& mLayerHandles;
+
+public:
+ FlingerDataMapper(std::unordered_map<BBinder* /* handle */, int32_t /* id */>& layerHandles)
+ : mLayerHandles(layerHandles) {}
+
+ int32_t getLayerId(const sp<IBinder>& layerHandle) const override {
+ if (layerHandle == nullptr) {
+ return -1;
+ }
+ auto it = mLayerHandles.find(layerHandle->localBinder());
+ if (it == mLayerHandles.end()) {
+ ALOGW("Could not find layer handle %p", layerHandle->localBinder());
+ return -1;
+ }
+ return it->second;
+ }
+
+ void getGraphicBufferPropertiesFromCache(client_cache_t cachedBuffer, uint64_t* outBufferId,
+ uint32_t* outWidth, uint32_t* outHeight,
+ int32_t* outPixelFormat,
+ uint64_t* outUsage) const override {
+ std::shared_ptr<renderengine::ExternalTexture> buffer =
+ ClientCache::getInstance().get(cachedBuffer);
+ if (!buffer || !buffer->getBuffer()) {
+ *outBufferId = 0;
+ *outWidth = 0;
+ *outHeight = 0;
+ *outPixelFormat = 0;
+ *outUsage = 0;
+ return;
+ }
+
+ *outBufferId = buffer->getId();
+ *outWidth = buffer->getWidth();
+ *outHeight = buffer->getHeight();
+ *outPixelFormat = buffer->getPixelFormat();
+ *outUsage = buffer->getUsage();
+ return;
+ }
+};
+
+TransactionTracing::TransactionTracing()
+ : mProtoParser(std::make_unique<FlingerDataMapper>(mLayerHandles)) {
std::scoped_lock lock(mTraceLock);
mBuffer.setSize(mBufferSizeInBytes);
@@ -85,11 +131,7 @@
void TransactionTracing::addQueuedTransaction(const TransactionState& transaction) {
std::scoped_lock lock(mTraceLock);
ATRACE_CALL();
- mQueuedTransactions[transaction.id] =
- TransactionProtoParser::toProto(transaction,
- std::bind(&TransactionTracing::getLayerIdLocked, this,
- std::placeholders::_1),
- nullptr);
+ mQueuedTransactions[transaction.id] = mProtoParser.toProto(transaction);
}
void TransactionTracing::addCommittedTransactions(std::vector<TransactionState>& transactions,
@@ -212,9 +254,7 @@
ALOGW("Duplicate handles found. %p", layerHandle);
}
mLayerHandles[layerHandle] = layerId;
- proto::LayerCreationArgs protoArgs = TransactionProtoParser::toProto(args);
- proto::LayerCreationArgs protoArgsCopy = protoArgs;
- mCreatedLayers.push_back(protoArgs);
+ mCreatedLayers.push_back(mProtoParser.toProto(args));
}
void TransactionTracing::onMirrorLayerAdded(BBinder* layerHandle, int layerId,
@@ -225,7 +265,7 @@
ALOGW("Duplicate handles found. %p", layerHandle);
}
mLayerHandles[layerHandle] = layerId;
- mCreatedLayers.emplace_back(TransactionProtoParser::toProto(args));
+ mCreatedLayers.emplace_back(mProtoParser.toProto(args));
}
void TransactionTracing::onLayerRemoved(int32_t layerId) {
@@ -263,18 +303,6 @@
}
}
-int32_t TransactionTracing::getLayerIdLocked(const sp<IBinder>& layerHandle) {
- if (layerHandle == nullptr) {
- return -1;
- }
- auto it = mLayerHandles.find(layerHandle->localBinder());
- if (it == mLayerHandles.end()) {
- ALOGW("Could not find layer handle %p", layerHandle->localBinder());
- return -1;
- }
- return it->second;
-}
-
void TransactionTracing::updateStartingStateLocked(
const proto::TransactionTraceEntry& removedEntry) {
mStartingTimestamp = removedEntry.elapsed_realtime_nanos();
@@ -283,7 +311,7 @@
for (const proto::LayerCreationArgs& addedLayer : removedEntry.added_layers()) {
TracingLayerState& startingState = mStartingStates[addedLayer.layer_id()];
startingState.layerId = addedLayer.layer_id();
- TransactionProtoParser::fromProto(addedLayer, startingState.args);
+ mProtoParser.fromProto(addedLayer, startingState.args);
}
// Merge layer states to starting transaction state.
@@ -294,7 +322,7 @@
ALOGW("Could not find layer id %d", layerState.layer_id());
continue;
}
- TransactionProtoParser::mergeFromProto(layerState, nullptr, it->second);
+ mProtoParser.mergeFromProto(layerState, it->second);
}
}
@@ -316,10 +344,10 @@
entryProto->mutable_added_layers()->Reserve(static_cast<int32_t>(mStartingStates.size()));
for (auto& [layerId, state] : mStartingStates) {
- entryProto->mutable_added_layers()->Add(TransactionProtoParser::toProto(state.args));
+ entryProto->mutable_added_layers()->Add(mProtoParser.toProto(state.args));
}
- proto::TransactionState transactionProto = TransactionProtoParser::toProto(mStartingStates);
+ proto::TransactionState transactionProto = mProtoParser.toProto(mStartingStates);
transactionProto.set_vsync_id(0);
transactionProto.set_post_time(mStartingTimestamp);
entryProto->mutable_transactions()->Add(std::move(transactionProto));
diff --git a/services/surfaceflinger/Tracing/TransactionTracing.h b/services/surfaceflinger/Tracing/TransactionTracing.h
index d5d98ce..c20f22a 100644
--- a/services/surfaceflinger/Tracing/TransactionTracing.h
+++ b/services/surfaceflinger/Tracing/TransactionTracing.h
@@ -84,6 +84,7 @@
GUARDED_BY(mTraceLock);
std::vector<int32_t /* layerId */> mRemovedLayerHandles GUARDED_BY(mTraceLock);
std::map<int32_t /* layerId */, TracingLayerState> mStartingStates GUARDED_BY(mTraceLock);
+ TransactionProtoParser mProtoParser GUARDED_BY(mTraceLock);
// We do not want main thread to block so main thread will try to acquire mMainThreadLock,
// otherwise will push data to temporary container.
diff --git a/services/surfaceflinger/tests/unittests/TransactionProtoParserTest.cpp b/services/surfaceflinger/tests/unittests/TransactionProtoParserTest.cpp
index 271b1c0..ab893a3 100644
--- a/services/surfaceflinger/tests/unittests/TransactionProtoParserTest.cpp
+++ b/services/surfaceflinger/tests/unittests/TransactionProtoParserTest.cpp
@@ -70,23 +70,32 @@
t1.displays.add(display);
}
- TransactionProtoParser::LayerHandleToIdFn getLayerIdFn = [&](const sp<IBinder>& handle) {
- return (handle == layerHandle) ? 42 : -1;
- };
- TransactionProtoParser::DisplayHandleToIdFn getDisplayIdFn = [&](const sp<IBinder>& handle) {
- return (handle == displayHandle) ? 43 : -1;
- };
- TransactionProtoParser::LayerIdToHandleFn getLayerHandleFn = [&](int32_t id) {
- return (id == 42) ? layerHandle : nullptr;
- };
- TransactionProtoParser::DisplayIdToHandleFn getDisplayHandleFn = [&](int32_t id) {
- return (id == 43) ? displayHandle : nullptr;
+ class TestMapper : public TransactionProtoParser::FlingerDataMapper {
+ public:
+ sp<IBinder> layerHandle;
+ sp<IBinder> displayHandle;
+
+ TestMapper(sp<IBinder> layerHandle, sp<IBinder> displayHandle)
+ : layerHandle(layerHandle), displayHandle(displayHandle) {}
+
+ sp<IBinder> getLayerHandle(int32_t id) const override {
+ return (id == 42) ? layerHandle : nullptr;
+ }
+ int32_t getLayerId(const sp<IBinder>& handle) const override {
+ return (handle == layerHandle) ? 42 : -1;
+ }
+ sp<IBinder> getDisplayHandle(int32_t id) const {
+ return (id == 43) ? displayHandle : nullptr;
+ }
+ int32_t getDisplayId(const sp<IBinder>& handle) const {
+ return (handle == displayHandle) ? 43 : -1;
+ }
};
- proto::TransactionState proto =
- TransactionProtoParser::toProto(t1, getLayerIdFn, getDisplayIdFn);
- TransactionState t2 =
- TransactionProtoParser::fromProto(proto, getLayerHandleFn, getDisplayHandleFn);
+ TransactionProtoParser parser(std::make_unique<TestMapper>(layerHandle, displayHandle));
+
+ proto::TransactionState proto = parser.toProto(t1);
+ TransactionState t2 = parser.fromProto(proto);
ASSERT_EQ(t1.originPid, t2.originPid);
ASSERT_EQ(t1.originUid, t2.originUid);
diff --git a/services/surfaceflinger/tests/unittests/TransactionTracingTest.cpp b/services/surfaceflinger/tests/unittests/TransactionTracingTest.cpp
index 39dbb07..61b72a0 100644
--- a/services/surfaceflinger/tests/unittests/TransactionTracingTest.cpp
+++ b/services/surfaceflinger/tests/unittests/TransactionTracingTest.cpp
@@ -178,8 +178,8 @@
// verify we can still retrieve the layer change from the first entry containing starting
// states.
EXPECT_GT(proto.entry().size(), 0);
- EXPECT_GT(proto.entry(0).transactions().size(), 0);
- EXPECT_GT(proto.entry(0).added_layers().size(), 0);
+ EXPECT_EQ(proto.entry(0).transactions().size(), 1);
+ EXPECT_EQ(proto.entry(0).added_layers().size(), 2);
EXPECT_EQ(proto.entry(0).transactions(0).layer_changes().size(), 2);
EXPECT_EQ(proto.entry(0).transactions(0).layer_changes(0).layer_id(), mParentLayerId);
EXPECT_EQ(proto.entry(0).transactions(0).layer_changes(0).z(), 42);