Merge "Define out the hwbinder death notifier code for libgui"
diff --git a/cmds/dumpsys/dumpsys.cpp b/cmds/dumpsys/dumpsys.cpp
index 5597bcd..a427c8d 100644
--- a/cmds/dumpsys/dumpsys.cpp
+++ b/cmds/dumpsys/dumpsys.cpp
@@ -29,6 +29,7 @@
#include <utils/Log.h>
#include <utils/Vector.h>
+#include <iostream>
#include <fcntl.h>
#include <getopt.h>
#include <stdio.h>
@@ -231,14 +232,14 @@
const size_t N = services.size();
if (N > 1) {
// first print a list of the current services
- aout << "Currently running services:" << endl;
+ std::cout << "Currently running services:" << std::endl;
for (size_t i=0; i<N; i++) {
sp<IBinder> service = sm_->checkService(services[i]);
if (service != nullptr) {
bool skipped = IsSkipped(skippedServices, services[i]);
- aout << " " << services[i] << (skipped ? " (skipped)" : "") << endl;
+ std::cout << " " << services[i] << (skipped ? " (skipped)" : "") << std::endl;
}
}
}
@@ -263,10 +264,10 @@
asProto, elapsedDuration, bytesWritten);
if (status == TIMED_OUT) {
- aout << endl
+ std::cout << std::endl
<< "*** SERVICE '" << serviceName << "' DUMP TIMEOUT (" << timeoutArgMs
- << "ms) EXPIRED ***" << endl
- << endl;
+ << "ms) EXPIRED ***" << std::endl
+ << std::endl;
}
if (addSeparator) {
@@ -332,14 +333,14 @@
const Vector<String16>& args) {
sp<IBinder> service = sm_->checkService(serviceName);
if (service == nullptr) {
- aerr << "Can't find service: " << serviceName << endl;
+ std::cerr << "Can't find service: " << serviceName << std::endl;
return NAME_NOT_FOUND;
}
int sfd[2];
if (pipe(sfd) != 0) {
- aerr << "Failed to create pipe to dump service info for " << serviceName << ": "
- << strerror(errno) << endl;
+ std::cerr << "Failed to create pipe to dump service info for " << serviceName << ": "
+ << strerror(errno) << std::endl;
return -errno;
}
@@ -359,13 +360,13 @@
err = dumpPidToFd(service, remote_end);
break;
default:
- aerr << "Unknown dump type" << static_cast<int>(type) << endl;
+ std::cerr << "Unknown dump type" << static_cast<int>(type) << std::endl;
return;
}
if (err != OK) {
- aerr << "Error dumping service info status_t: " << statusToString(err) << " "
- << serviceName << endl;
+ std::cerr << "Error dumping service info status_t: " << statusToString(err) << " "
+ << serviceName << std::endl;
}
});
return OK;
@@ -422,8 +423,8 @@
int rc = TEMP_FAILURE_RETRY(poll(&pfd, 1, time_left_ms()));
if (rc < 0) {
- aerr << "Error in poll while dumping service " << serviceName << " : "
- << strerror(errno) << endl;
+ std::cerr << "Error in poll while dumping service " << serviceName << " : "
+ << strerror(errno) << std::endl;
status = -errno;
break;
} else if (rc == 0) {
@@ -434,8 +435,8 @@
char buf[4096];
rc = TEMP_FAILURE_RETRY(read(redirectFd_.get(), buf, sizeof(buf)));
if (rc < 0) {
- aerr << "Failed to read while dumping service " << serviceName << ": "
- << strerror(errno) << endl;
+ std::cerr << "Failed to read while dumping service " << serviceName << ": "
+ << strerror(errno) << std::endl;
status = -errno;
break;
} else if (rc == 0) {
@@ -444,8 +445,8 @@
}
if (!WriteFully(fd, buf, rc)) {
- aerr << "Failed to write while dumping service " << serviceName << ": "
- << strerror(errno) << endl;
+ std::cerr << "Failed to write while dumping service " << serviceName << ": "
+ << strerror(errno) << std::endl;
status = -errno;
break;
}
diff --git a/cmds/dumpsys/main.cpp b/cmds/dumpsys/main.cpp
index 8ba0eba..fa4cc97 100644
--- a/cmds/dumpsys/main.cpp
+++ b/cmds/dumpsys/main.cpp
@@ -21,10 +21,9 @@
#include "dumpsys.h"
#include <binder/IServiceManager.h>
-#include <binder/TextOutput.h>
+#include <iostream>
#include <signal.h>
-#include <stdio.h>
using namespace android;
@@ -34,7 +33,7 @@
fflush(stdout);
if (sm == nullptr) {
ALOGE("Unable to get default service manager!");
- aerr << "dumpsys: Unable to get default service manager!" << endl;
+ std::cerr << "dumpsys: Unable to get default service manager!" << std::endl;
return 20;
}
diff --git a/libs/binder/IPCThreadState.cpp b/libs/binder/IPCThreadState.cpp
index 4dcd07a..9e89c57 100644
--- a/libs/binder/IPCThreadState.cpp
+++ b/libs/binder/IPCThreadState.cpp
@@ -1230,6 +1230,11 @@
if (error < NO_ERROR) reply.setError(error);
sendReply(reply, 0);
} else {
+ if (error != OK || reply.dataSize() != 0) {
+ alog << "oneway function results will be dropped but finished with status "
+ << statusToString(error)
+ << " and parcel size " << reply.dataSize() << endl;
+ }
LOG_ONEWAY("NOT sending reply to %d!", mCallingPid);
}
diff --git a/libs/binder/tests/Android.bp b/libs/binder/tests/Android.bp
index 5a7f9a9..3ee8187 100644
--- a/libs/binder/tests/Android.bp
+++ b/libs/binder/tests/Android.bp
@@ -40,7 +40,7 @@
},
srcs: ["binderDriverInterfaceTest.cpp"],
- test_suites: ["device-tests"],
+ test_suites: ["device-tests", "vts-core"],
}
cc_test {
@@ -69,7 +69,7 @@
"libbinder",
"libutils",
],
- test_suites: ["device-tests"],
+ test_suites: ["device-tests", "vts-core"],
require_root: true,
}
@@ -131,7 +131,7 @@
"liblog",
"libutils",
],
- test_suites: ["device-tests"],
+ test_suites: ["device-tests", "vts-core"],
require_root: true,
}
diff --git a/services/surfaceflinger/Scheduler/EventThread.cpp b/services/surfaceflinger/Scheduler/EventThread.cpp
index 14e3ec6..acab5a6 100644
--- a/services/surfaceflinger/Scheduler/EventThread.cpp
+++ b/services/surfaceflinger/Scheduler/EventThread.cpp
@@ -335,6 +335,11 @@
mCondition.notify_all();
}
+size_t EventThread::getEventThreadConnectionCount() {
+ std::lock_guard<std::mutex> lock(mMutex);
+ return mDisplayEventConnections.size();
+}
+
void EventThread::threadMain(std::unique_lock<std::mutex>& lock) {
DisplayEventConsumers consumers;
diff --git a/services/surfaceflinger/Scheduler/EventThread.h b/services/surfaceflinger/Scheduler/EventThread.h
index 641b2a5..466234d 100644
--- a/services/surfaceflinger/Scheduler/EventThread.h
+++ b/services/surfaceflinger/Scheduler/EventThread.h
@@ -16,7 +16,12 @@
#pragma once
+#include <android-base/thread_annotations.h>
+#include <gui/DisplayEventReceiver.h>
+#include <gui/IDisplayEventConnection.h>
+#include <private/gui/BitTube.h>
#include <sys/types.h>
+#include <utils/Errors.h>
#include <condition_variable>
#include <cstdint>
@@ -26,13 +31,6 @@
#include <thread>
#include <vector>
-#include <android-base/thread_annotations.h>
-
-#include <gui/DisplayEventReceiver.h>
-#include <gui/IDisplayEventConnection.h>
-#include <private/gui/BitTube.h>
-
-#include <utils/Errors.h>
#include "HwcStrongTypes.h"
// ---------------------------------------------------------------------------
@@ -134,6 +132,9 @@
// Usage of this method assumes that only the primary internal display
// supports multiple display configurations.
virtual void requestLatestConfig() = 0;
+
+ // Retrieves the number of event connections tracked by this EventThread.
+ virtual size_t getEventThreadConnectionCount() = 0;
};
namespace impl {
@@ -168,6 +169,8 @@
void setPhaseOffset(nsecs_t phaseOffset) override;
+ size_t getEventThreadConnectionCount() override;
+
private:
friend EventThreadTest;
diff --git a/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp b/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp
index 8202515..d1de737 100644
--- a/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp
+++ b/services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp
@@ -194,9 +194,22 @@
}
}
- float max = 0;
+ // Now that we scored all the refresh rates we need to pick the one that got the highest score.
+ // In case of a tie we will pick the higher refresh rate if any of the layers wanted Max,
+ // or the lower otherwise.
+ const RefreshRate* bestRefreshRate = maxVoteLayers > 0
+ ? getBestRefreshRate(scores.rbegin(), scores.rend())
+ : getBestRefreshRate(scores.begin(), scores.end());
+
+ return bestRefreshRate == nullptr ? *mCurrentRefreshRate : *bestRefreshRate;
+}
+
+template <typename Iter>
+const RefreshRate* RefreshRateConfigs::getBestRefreshRate(Iter begin, Iter end) const {
const RefreshRate* bestRefreshRate = nullptr;
- for (const auto [refreshRate, score] : scores) {
+ float max = 0;
+ for (auto i = begin; i != end; ++i) {
+ const auto [refreshRate, score] = *i;
ALOGV("%s scores %.2f", refreshRate->name.c_str(), score);
ATRACE_INT(refreshRate->name.c_str(), round<int>(score * 100));
@@ -207,7 +220,7 @@
}
}
- return bestRefreshRate == nullptr ? *mCurrentRefreshRate : *bestRefreshRate;
+ return bestRefreshRate;
}
const AllRefreshRatesMapType& RefreshRateConfigs::getAllRefreshRates() const {
diff --git a/services/surfaceflinger/Scheduler/RefreshRateConfigs.h b/services/surfaceflinger/Scheduler/RefreshRateConfigs.h
index e5bb557..1132a8c 100644
--- a/services/surfaceflinger/Scheduler/RefreshRateConfigs.h
+++ b/services/surfaceflinger/Scheduler/RefreshRateConfigs.h
@@ -182,6 +182,12 @@
const std::function<bool(const RefreshRate&)>& shouldAddRefreshRate,
std::vector<const RefreshRate*>* outRefreshRates);
+ // Returns the refresh rate with the highest score in the collection specified from begin
+ // to end. If there are more than one with the same highest refresh rate, the first one is
+ // returned.
+ template <typename Iter>
+ const RefreshRate* getBestRefreshRate(Iter begin, Iter end) const;
+
// The list of refresh rates, indexed by display config ID. This must not change after this
// object is initialized.
AllRefreshRatesMapType mRefreshRates;
diff --git a/services/surfaceflinger/Scheduler/Scheduler.cpp b/services/surfaceflinger/Scheduler/Scheduler.cpp
index 331c8a8..71ac90e 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.cpp
+++ b/services/surfaceflinger/Scheduler/Scheduler.cpp
@@ -230,6 +230,11 @@
mConnections[handle].thread->onConfigChanged(displayId, configId, vsyncPeriod);
}
+size_t Scheduler::getEventThreadConnectionCount(ConnectionHandle handle) {
+ RETURN_IF_INVALID_HANDLE(handle, 0);
+ return mConnections[handle].thread->getEventThreadConnectionCount();
+}
+
void Scheduler::dump(ConnectionHandle handle, std::string& result) const {
RETURN_IF_INVALID_HANDLE(handle);
mConnections.at(handle).thread->dump(result);
diff --git a/services/surfaceflinger/Scheduler/Scheduler.h b/services/surfaceflinger/Scheduler/Scheduler.h
index 82b78e3..81051be 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.h
+++ b/services/surfaceflinger/Scheduler/Scheduler.h
@@ -145,6 +145,8 @@
// Notifies the scheduler when the display size has changed. Called from SF's main thread
void onPrimaryDisplayAreaChanged(uint32_t displayArea);
+ size_t getEventThreadConnectionCount(ConnectionHandle handle);
+
private:
friend class TestableScheduler;
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index f81179a..d971625 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -2119,6 +2119,10 @@
mTimeStats->setPresentFenceGlobal(presentFenceTime);
+ const size_t sfConnections = mScheduler->getEventThreadConnectionCount(mSfConnectionHandle);
+ const size_t appConnections = mScheduler->getEventThreadConnectionCount(mAppConnectionHandle);
+ mTimeStats->recordDisplayEventConnectionCount(sfConnections + appConnections);
+
if (displayDevice && getHwComposer().isConnected(*displayDevice->getId()) &&
!displayDevice->isPoweredOn()) {
return;
diff --git a/services/surfaceflinger/SurfaceFlingerFactory.h b/services/surfaceflinger/SurfaceFlingerFactory.h
index 951bd09..c7da730 100644
--- a/services/surfaceflinger/SurfaceFlingerFactory.h
+++ b/services/surfaceflinger/SurfaceFlingerFactory.h
@@ -16,14 +16,14 @@
#pragma once
+#include <cutils/compiler.h>
+#include <utils/StrongPointer.h>
+
#include <cinttypes>
#include <functional>
#include <memory>
#include <string>
-#include <cutils/compiler.h>
-#include <utils/StrongPointer.h>
-
namespace android {
typedef int32_t PixelFormat;
diff --git a/services/surfaceflinger/TimeStats/TimeStats.cpp b/services/surfaceflinger/TimeStats/TimeStats.cpp
index b2cce7c..7c8c28e 100644
--- a/services/surfaceflinger/TimeStats/TimeStats.cpp
+++ b/services/surfaceflinger/TimeStats/TimeStats.cpp
@@ -70,6 +70,7 @@
mStatsDelegate->statsEventWriteInt64(event, mTimeStats.clientCompositionFrames);
mStatsDelegate->statsEventWriteInt64(event, mTimeStats.displayOnTime);
mStatsDelegate->statsEventWriteInt64(event, mTimeStats.presentToPresent.totalTime());
+ mStatsDelegate->statsEventWriteInt32(event, mTimeStats.displayEventConnectionsCount);
mStatsDelegate->statsEventBuild(event);
clearGlobalLocked();
@@ -272,6 +273,16 @@
mTimeStats.clientCompositionReusedFrames++;
}
+void TimeStats::recordDisplayEventConnectionCount(int32_t count) {
+ if (!mEnabled.load()) return;
+
+ ATRACE_CALL();
+
+ std::lock_guard<std::mutex> lock(mMutex);
+ mTimeStats.displayEventConnectionsCount =
+ std::max(mTimeStats.displayEventConnectionsCount, count);
+}
+
static int32_t msBetween(nsecs_t start, nsecs_t end) {
int64_t delta = std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::nanoseconds(end - start))
@@ -815,6 +826,7 @@
mTimeStats.missedFrames = 0;
mTimeStats.clientCompositionFrames = 0;
mTimeStats.clientCompositionReusedFrames = 0;
+ mTimeStats.displayEventConnectionsCount = 0;
mTimeStats.displayOnTime = 0;
mTimeStats.presentToPresent.hist.clear();
mTimeStats.frameDuration.hist.clear();
diff --git a/services/surfaceflinger/TimeStats/TimeStats.h b/services/surfaceflinger/TimeStats/TimeStats.h
index a428ef4..ddebeb1 100644
--- a/services/surfaceflinger/TimeStats/TimeStats.h
+++ b/services/surfaceflinger/TimeStats/TimeStats.h
@@ -52,6 +52,9 @@
virtual void incrementMissedFrames() = 0;
virtual void incrementClientCompositionFrames() = 0;
virtual void incrementClientCompositionReusedFrames() = 0;
+ // Records the most up-to-date count of display event connections.
+ // The stored count will be the maximum ever recoded.
+ virtual void recordDisplayEventConnectionCount(int32_t count) = 0;
// Records the start and end times for a frame.
// The start time is the same as the beginning of a SurfaceFlinger
@@ -177,6 +180,10 @@
return AStatsEvent_setAtomId(event, atom_id);
}
+ virtual void statsEventWriteInt32(AStatsEvent* event, int32_t field) {
+ return AStatsEvent_writeInt32(event, field);
+ }
+
virtual void statsEventWriteInt64(AStatsEvent* event, int64_t field) {
return AStatsEvent_writeInt64(event, field);
}
@@ -208,6 +215,7 @@
void incrementMissedFrames() override;
void incrementClientCompositionFrames() override;
void incrementClientCompositionReusedFrames() override;
+ void recordDisplayEventConnectionCount(int32_t count) override;
void recordFrameDuration(nsecs_t startTime, nsecs_t endTime) override;
void recordRenderEngineDuration(nsecs_t startTime, nsecs_t endTime) override;
diff --git a/services/surfaceflinger/TimeStats/timestatsproto/include/timestatsproto/TimeStatsHelper.h b/services/surfaceflinger/TimeStats/timestatsproto/include/timestatsproto/TimeStatsHelper.h
index e374b73..5e7c449 100644
--- a/services/surfaceflinger/TimeStats/timestatsproto/include/timestatsproto/TimeStatsHelper.h
+++ b/services/surfaceflinger/TimeStats/timestatsproto/include/timestatsproto/TimeStatsHelper.h
@@ -62,6 +62,7 @@
int32_t missedFrames = 0;
int32_t clientCompositionFrames = 0;
int32_t clientCompositionReusedFrames = 0;
+ int32_t displayEventConnectionsCount = 0;
int64_t displayOnTime = 0;
Histogram presentToPresent;
Histogram frameDuration;
diff --git a/services/surfaceflinger/tests/SurfaceFlinger_test.filter b/services/surfaceflinger/tests/SurfaceFlinger_test.filter
index 2bedd7d..cf7d570 100644
--- a/services/surfaceflinger/tests/SurfaceFlinger_test.filter
+++ b/services/surfaceflinger/tests/SurfaceFlinger_test.filter
@@ -1,5 +1,5 @@
{
"presubmit": {
- "filter": "*:-LayerTypeAndRenderTypeTransactionTests/LayerTypeAndRenderTypeTransactionTest.SetCornerRadius/2:LayerTypeAndRenderTypeTransactionTests/LayerTypeAndRenderTypeTransactionTest.SetCornerRadius/3:LayerTypeAndRenderTypeTransactionTests/LayerTypeAndRenderTypeTransactionTest.SetCornerRadiusChildCrop/2:LayerTypeAndRenderTypeTransactionTests/LayerTypeAndRenderTypeTransactionTest.SetCornerRadiusChildCrop/3"
+ "filter": ""
}
}
diff --git a/services/surfaceflinger/tests/unittests/EventThreadTest.cpp b/services/surfaceflinger/tests/unittests/EventThreadTest.cpp
index 61d4f47..65b3e35 100644
--- a/services/surfaceflinger/tests/unittests/EventThreadTest.cpp
+++ b/services/surfaceflinger/tests/unittests/EventThreadTest.cpp
@@ -19,9 +19,7 @@
#include <gmock/gmock.h>
#include <gtest/gtest.h>
-
#include <log/log.h>
-
#include <utils/Errors.h>
#include "AsyncCallRecorder.h"
@@ -401,6 +399,34 @@
expectVSyncSetEnabledCallReceived(false);
}
+TEST_F(EventThreadTest, tracksEventConnections) {
+ EXPECT_EQ(1, mThread->getEventThreadConnectionCount());
+ ConnectionEventRecorder errorConnectionEventRecorder{NO_MEMORY};
+ sp<MockEventThreadConnection> errorConnection =
+ createConnection(errorConnectionEventRecorder,
+ ISurfaceComposer::eConfigChangedSuppress);
+ mThread->setVsyncRate(1, errorConnection);
+ EXPECT_EQ(2, mThread->getEventThreadConnectionCount());
+ ConnectionEventRecorder secondConnectionEventRecorder{0};
+ sp<MockEventThreadConnection> secondConnection =
+ createConnection(secondConnectionEventRecorder,
+ ISurfaceComposer::eConfigChangedSuppress);
+ mThread->setVsyncRate(1, secondConnection);
+ EXPECT_EQ(3, mThread->getEventThreadConnectionCount());
+
+ // EventThread should enable vsync callbacks.
+ expectVSyncSetEnabledCallReceived(true);
+
+ // The first event will be seen by the interceptor, and by the connection,
+ // which then returns an error.
+ mCallback->onVSyncEvent(123);
+ expectInterceptCallReceived(123);
+ expectVsyncEventReceivedByConnection("errorConnection", errorConnectionEventRecorder, 123, 1u);
+ expectVsyncEventReceivedByConnection("successConnection", secondConnectionEventRecorder, 123,
+ 1u);
+ EXPECT_EQ(2, mThread->getEventThreadConnectionCount());
+}
+
TEST_F(EventThreadTest, eventsDroppedIfNonfatalEventDeliveryError) {
ConnectionEventRecorder errorConnectionEventRecorder{WOULD_BLOCK};
sp<MockEventThreadConnection> errorConnection =
diff --git a/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp b/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp
index 841c624..99c5f3d 100644
--- a/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp
+++ b/services/surfaceflinger/tests/unittests/RefreshRateConfigsTest.cpp
@@ -745,6 +745,44 @@
}
}
+TEST_F(RefreshRateConfigsTest, twoDeviceConfigs_getRefreshRateForContentV2_Multiples) {
+ std::vector<RefreshRateConfigs::InputConfig> configs{
+ {{HWC_CONFIG_ID_60, HWC_GROUP_ID_0, VSYNC_60},
+ {HWC_CONFIG_ID_90, HWC_GROUP_ID_0, VSYNC_90}}};
+ auto refreshRateConfigs =
+ std::make_unique<RefreshRateConfigs>(configs, /*currentConfigId=*/HWC_CONFIG_ID_60);
+
+ RefreshRate expected60Config = {HWC_CONFIG_ID_60, VSYNC_60, HWC_GROUP_ID_0, "60fps", 60};
+ RefreshRate expected90Config = {HWC_CONFIG_ID_90, VSYNC_90, HWC_GROUP_ID_0, "90fps", 90};
+
+ auto layers = std::vector<LayerRequirement>{LayerRequirement{.weight = 1.0f},
+ LayerRequirement{.weight = 1.0f}};
+ auto& lr1 = layers[0];
+ auto& lr2 = layers[1];
+
+ lr1.vote = LayerVoteType::ExplicitExactOrMultiple;
+ lr1.desiredRefreshRate = 60.0f;
+ lr2.vote = LayerVoteType::Heuristic;
+ lr2.desiredRefreshRate = 90.0f;
+ EXPECT_EQ(expected60Config, refreshRateConfigs->getRefreshRateForContentV2(layers));
+
+ lr1.vote = LayerVoteType::ExplicitExactOrMultiple;
+ lr1.desiredRefreshRate = 60.0f;
+ lr2.vote = LayerVoteType::Max;
+ EXPECT_EQ(expected60Config, refreshRateConfigs->getRefreshRateForContentV2(layers));
+
+ lr1.vote = LayerVoteType::ExplicitExactOrMultiple;
+ lr1.desiredRefreshRate = 30.0f;
+ lr2.vote = LayerVoteType::Heuristic;
+ lr2.desiredRefreshRate = 90.0f;
+ EXPECT_EQ(expected90Config, refreshRateConfigs->getRefreshRateForContentV2(layers));
+
+ lr1.vote = LayerVoteType::ExplicitExactOrMultiple;
+ lr1.desiredRefreshRate = 30.0f;
+ lr2.vote = LayerVoteType::Max;
+ EXPECT_EQ(expected90Config, refreshRateConfigs->getRefreshRateForContentV2(layers));
+}
+
} // namespace
} // namespace scheduler
} // namespace android
diff --git a/services/surfaceflinger/tests/unittests/SchedulerTest.cpp b/services/surfaceflinger/tests/unittests/SchedulerTest.cpp
index 89002a8..5db11ec 100644
--- a/services/surfaceflinger/tests/unittests/SchedulerTest.cpp
+++ b/services/surfaceflinger/tests/unittests/SchedulerTest.cpp
@@ -159,6 +159,11 @@
EXPECT_CALL(*mEventThread, setPhaseOffset(10)).Times(1);
ASSERT_NO_FATAL_FAILURE(mScheduler->setPhaseOffset(mConnectionHandle, 10));
+
+ static constexpr size_t kEventConnections = 5;
+ ON_CALL(*mEventThread, getEventThreadConnectionCount())
+ .WillByDefault(Return(kEventConnections));
+ EXPECT_EQ(kEventConnections, mScheduler->getEventThreadConnectionCount(mConnectionHandle));
}
} // namespace
diff --git a/services/surfaceflinger/tests/unittests/TimeStatsTest.cpp b/services/surfaceflinger/tests/unittests/TimeStatsTest.cpp
index fb2e3bd..685dfba 100644
--- a/services/surfaceflinger/tests/unittests/TimeStatsTest.cpp
+++ b/services/surfaceflinger/tests/unittests/TimeStatsTest.cpp
@@ -166,6 +166,7 @@
MOCK_METHOD1(unregisterStatsPullAtomCallback, void(int32_t));
MOCK_METHOD2(statsEventSetAtomId, void(AStatsEvent*, uint32_t));
+ MOCK_METHOD2(statsEventWriteInt32, void(AStatsEvent*, int32_t));
MOCK_METHOD2(statsEventWriteInt64, void(AStatsEvent*, int64_t));
MOCK_METHOD2(statsEventWriteString8, void(AStatsEvent*, const char*));
MOCK_METHOD3(statsEventWriteByteArray, void(AStatsEvent*, const uint8_t*, size_t));
@@ -800,6 +801,7 @@
constexpr size_t TOTAL_FRAMES = 5;
constexpr size_t MISSED_FRAMES = 4;
constexpr size_t CLIENT_COMPOSITION_FRAMES = 3;
+ constexpr size_t DISPLAY_EVENT_CONNECTIONS = 14;
mTimeStats->onBootFinished();
EXPECT_TRUE(inputCommand(InputCommand::ENABLE, FMT_STRING).empty());
@@ -814,6 +816,8 @@
mTimeStats->incrementClientCompositionFrames();
}
+ mTimeStats->recordDisplayEventConnectionCount(DISPLAY_EVENT_CONNECTIONS);
+
mTimeStats->setPowerMode(HWC_POWER_MODE_NORMAL);
mTimeStats->setPresentFenceGlobal(std::make_shared<FenceTime>(3000000));
mTimeStats->setPresentFenceGlobal(std::make_shared<FenceTime>(5000000));
@@ -834,6 +838,7 @@
EXPECT_CALL(*mDelegate, statsEventWriteInt64(mDelegate->mEvent, CLIENT_COMPOSITION_FRAMES));
EXPECT_CALL(*mDelegate, statsEventWriteInt64(mDelegate->mEvent, _));
EXPECT_CALL(*mDelegate, statsEventWriteInt64(mDelegate->mEvent, 2));
+ EXPECT_CALL(*mDelegate, statsEventWriteInt32(mDelegate->mEvent, DISPLAY_EVENT_CONNECTIONS));
EXPECT_CALL(*mDelegate, statsEventBuild(mDelegate->mEvent));
}
EXPECT_EQ(AStatsManager_PULL_SUCCESS,
diff --git a/services/surfaceflinger/tests/unittests/mock/MockEventThread.h b/services/surfaceflinger/tests/unittests/mock/MockEventThread.h
index 9bda095..50eb390 100644
--- a/services/surfaceflinger/tests/unittests/mock/MockEventThread.h
+++ b/services/surfaceflinger/tests/unittests/mock/MockEventThread.h
@@ -42,6 +42,7 @@
MOCK_METHOD1(requestNextVsync, void(const sp<android::EventThreadConnection> &));
MOCK_METHOD0(requestLatestConfig, void());
MOCK_METHOD1(pauseVsyncCallback, void(bool));
+ MOCK_METHOD0(getEventThreadConnectionCount, size_t());
};
} // namespace mock
diff --git a/services/surfaceflinger/tests/unittests/mock/MockTimeStats.h b/services/surfaceflinger/tests/unittests/mock/MockTimeStats.h
index 2720537..c45d584 100644
--- a/services/surfaceflinger/tests/unittests/mock/MockTimeStats.h
+++ b/services/surfaceflinger/tests/unittests/mock/MockTimeStats.h
@@ -36,6 +36,7 @@
MOCK_METHOD0(incrementMissedFrames, void());
MOCK_METHOD0(incrementClientCompositionFrames, void());
MOCK_METHOD0(incrementClientCompositionReusedFrames, void());
+ MOCK_METHOD1(recordDisplayEventConnectionCount, void(int32_t));
MOCK_METHOD2(recordFrameDuration, void(nsecs_t, nsecs_t));
MOCK_METHOD2(recordRenderEngineDuration, void(nsecs_t, nsecs_t));
MOCK_METHOD2(recordRenderEngineDuration, void(nsecs_t, const std::shared_ptr<FenceTime>&));