Merge "Add metrics for logging SurfaceControl events" into main
diff --git a/services/surfaceflinger/Android.bp b/services/surfaceflinger/Android.bp
index 7babd17..d500ae8 100644
--- a/services/surfaceflinger/Android.bp
+++ b/services/surfaceflinger/Android.bp
@@ -82,6 +82,7 @@
"libpowermanager",
"libprocessgroup",
"libprotobuf-cpp-lite",
+ "libstatslog_surfaceflinger",
"libsync",
"libui",
"libutils",
@@ -313,3 +314,37 @@
"libSurfaceFlingerProperties",
],
}
+
+cc_library {
+ name: "libstatslog_surfaceflinger",
+ generated_sources: ["statslog_surfaceflinger.cpp"],
+ generated_headers: ["statslog_surfaceflinger.h"],
+ export_generated_headers: ["statslog_surfaceflinger.h"],
+ shared_libs: [
+ "libbinder",
+ "libstatsbootstrap",
+ "libutils",
+ "android.os.statsbootstrap_aidl-cpp",
+ ],
+}
+
+genrule {
+ name: "statslog_surfaceflinger.h",
+ tools: ["stats-log-api-gen"],
+ cmd: "$(location stats-log-api-gen) --header $(genDir)/statslog_surfaceflinger.h" +
+ " --module surfaceflinger --namespace android,surfaceflinger,stats --bootstrap",
+ out: [
+ "statslog_surfaceflinger.h",
+ ],
+}
+
+genrule {
+ name: "statslog_surfaceflinger.cpp",
+ tools: ["stats-log-api-gen"],
+ cmd: "$(location stats-log-api-gen) --cpp $(genDir)/statslog_surfaceflinger.cpp" +
+ " --module surfaceflinger --namespace android,surfaceflinger,stats" +
+ " --importHeader statslog_surfaceflinger.h --bootstrap",
+ out: [
+ "statslog_surfaceflinger.cpp",
+ ],
+}
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index e5dc2ee..c88092b 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -185,6 +185,14 @@
mFlinger->onLayerDestroyed(this);
+ const auto currentTime = std::chrono::steady_clock::now();
+ if (mBufferInfo.mTimeSinceDataspaceUpdate > std::chrono::steady_clock::time_point::min()) {
+ mFlinger->mLayerEvents.emplace_back(mOwnerUid, getSequence(), mBufferInfo.mDataspace,
+ std::chrono::duration_cast<std::chrono::milliseconds>(
+ currentTime -
+ mBufferInfo.mTimeSinceDataspaceUpdate));
+ }
+
if (mDrawingState.sidebandStream != nullptr) {
mFlinger->mTunnelModeEnabledReporter->decrementTunnelModeCount();
}
@@ -1261,8 +1269,17 @@
}
}
}
- if (lastDataspace != mBufferInfo.mDataspace) {
+ if (lastDataspace != mBufferInfo.mDataspace ||
+ mBufferInfo.mTimeSinceDataspaceUpdate == std::chrono::steady_clock::time_point::min()) {
mFlinger->mHdrLayerInfoChanged = true;
+ const auto currentTime = std::chrono::steady_clock::now();
+ if (mBufferInfo.mTimeSinceDataspaceUpdate > std::chrono::steady_clock::time_point::min()) {
+ mFlinger->mLayerEvents
+ .emplace_back(mOwnerUid, getSequence(), lastDataspace,
+ std::chrono::duration_cast<std::chrono::milliseconds>(
+ currentTime - mBufferInfo.mTimeSinceDataspaceUpdate));
+ }
+ mBufferInfo.mTimeSinceDataspaceUpdate = currentTime;
}
if (mBufferInfo.mDesiredHdrSdrRatio != mDrawingState.desiredHdrSdrRatio) {
mBufferInfo.mDesiredHdrSdrRatio = mDrawingState.desiredHdrSdrRatio;
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 871ad5e..a2716c6 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -242,6 +242,8 @@
sp<Fence> mFence;
uint32_t mTransform{0};
ui::Dataspace mDataspace{ui::Dataspace::UNKNOWN};
+ std::chrono::steady_clock::time_point mTimeSinceDataspaceUpdate =
+ std::chrono::steady_clock::time_point::min();
Rect mCrop;
PixelFormat mPixelFormat{PIXEL_FORMAT_NONE};
bool mTransformToDisplayInverse{false};
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index acf50f0..09dbc59 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -83,6 +83,7 @@
#include <renderengine/RenderEngine.h>
#include <renderengine/impl/ExternalTexture.h>
#include <scheduler/FrameTargeter.h>
+#include <statslog_surfaceflinger.h>
#include <sys/types.h>
#include <ui/ColorSpace.h>
#include <ui/DebugUtils.h>
@@ -3143,6 +3144,19 @@
mAddingHDRLayerInfoListener = false;
}
+ for (const auto& layerEvent : mLayerEvents) {
+ auto result =
+ stats::stats_write(stats::SURFACE_CONTROL_EVENT,
+ static_cast<int32_t>(layerEvent.uid),
+ static_cast<int64_t>(layerEvent.timeSinceLastEvent.count()),
+ static_cast<int32_t>(layerEvent.dataspace));
+ if (result < 0) {
+ ALOGW("Failed to report layer event with error: %d", result);
+ }
+ }
+
+ mLayerEvents.clear();
+
if (haveNewListeners || mHdrLayerInfoChanged) {
for (auto& [compositionDisplay, listener] : hdrInfoListeners) {
HdrLayerInfoReporter::HdrLayerInfo info;
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index db0e15e..31218ed 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -1221,6 +1221,14 @@
bool mHdrLayerInfoChanged = false;
+ struct LayerEvent {
+ uid_t uid;
+ int32_t layerId;
+ ui::Dataspace dataspace;
+ std::chrono::milliseconds timeSinceLastEvent;
+ };
+ std::vector<LayerEvent> mLayerEvents;
+
// Used to ensure we omit a callback when HDR layer info listener is newly added but the
// scene hasn't changed
bool mAddingHDRLayerInfoListener = false;
diff --git a/services/surfaceflinger/tests/unittests/Android.bp b/services/surfaceflinger/tests/unittests/Android.bp
index f1bd87c..40a6fb8 100644
--- a/services/surfaceflinger/tests/unittests/Android.bp
+++ b/services/surfaceflinger/tests/unittests/Android.bp
@@ -199,6 +199,7 @@
"libpowermanager",
"libprocessgroup",
"libprotobuf-cpp-lite",
+ "libstatslog_surfaceflinger",
"libSurfaceFlingerProp",
"libsync",
"libui",