Loading libs/binder/tests/parcel_fuzzer/Android.bp +2 −1 Original line number Diff line number Diff line Loading @@ -29,7 +29,6 @@ cc_fuzz { "libcutils", "libhidlbase", "liblog", "libutils", ], target: { Loading @@ -37,12 +36,14 @@ cc_fuzz { shared_libs: [ "libbinder_ndk", "libbinder", "libutils", ], }, host: { static_libs: [ "libbinder_ndk", "libbinder", "libutils", ], }, darwin: { Loading services/surfaceflinger/DisplayHardware/PowerAdvisor.cpp +25 −13 Original line number Diff line number Diff line Loading @@ -463,29 +463,41 @@ void AidlPowerHalWrapper::sendActualWorkDuration(int64_t actualDurationNanos, ALOGV("Failed to send actual work duration, skipping"); return; } WorkDuration duration; duration.durationNanos = actualDurationNanos; mActualDuration = actualDurationNanos; nsecs_t reportedDuration = actualDurationNanos; // normalize the sent values to a pre-set target if (sNormalizeTarget) { duration.durationNanos += mLastTargetDurationSent - mTargetDuration; } reportedDuration += mLastTargetDurationSent - mTargetDuration; } else { // when target duration change is within deviation and not updated, adjust the actual // duration proportionally based on the difference, e.g. if new target is 5ms longer than // last reported but actual duration is the same as last target, we want to report a smaller // actual work duration now to indicate that we are overshooting if (mLastTargetDurationSent != kDefaultTarget.count() && mTargetDuration != 0) { reportedDuration = static_cast<int64_t>(static_cast<long double>(mLastTargetDurationSent) / mTargetDuration * actualDurationNanos); mActualDuration = reportedDuration; } } mActualDuration = reportedDuration; WorkDuration duration; duration.durationNanos = reportedDuration; duration.timeStampNanos = timeStampNanos; mPowerHintQueue.push_back(duration); nsecs_t targetNsec = mTargetDuration; nsecs_t durationNsec = actualDurationNanos; if (sTraceHintSessionData) { ATRACE_INT64("Measured duration", durationNsec); ATRACE_INT64("Target error term", targetNsec - durationNsec); ATRACE_INT64("Measured duration", actualDurationNanos); ATRACE_INT64("Target error term", mTargetDuration - actualDurationNanos); ATRACE_INT64("Reported duration", reportedDuration); ATRACE_INT64("Reported target", mLastTargetDurationSent); ATRACE_INT64("Reported target error term", mLastTargetDurationSent - reportedDuration); } ALOGV("Sending actual work duration of: %" PRId64 " on target: %" PRId64 ALOGV("Sending actual work duration of: %" PRId64 " on reported target: %" PRId64 " with error: %" PRId64, durationNsec, targetNsec, targetNsec - durationNsec); reportedDuration, mLastTargetDurationSent, mLastTargetDurationSent - reportedDuration); // This rate limiter queues similar duration reports to the powerhal into // batches to avoid excessive binder calls. The criteria to send a given batch Loading @@ -501,7 +513,7 @@ void AidlPowerHalWrapper::sendActualWorkDuration(int64_t actualDurationNanos, } mPowerHintQueue.clear(); // we save the non-normalized value here to detect % changes mLastActualDurationSent = actualDurationNanos; mLastActualDurationSent = reportedDuration; } } Loading services/surfaceflinger/DisplayHardware/PowerAdvisor.h +2 −2 Original line number Diff line number Diff line Loading @@ -173,8 +173,8 @@ private: // Max percent the actual duration can vary without causing a report (eg: 0.1 = 10%) static constexpr double kAllowedActualDeviationPercent = 0.1; // Max percent the target duration can vary without causing a report (eg: 0.05 = 5%) static constexpr double kAllowedTargetDeviationPercent = 0.05; // Max percent the target duration can vary without causing a report (eg: 0.1 = 10%) static constexpr double kAllowedTargetDeviationPercent = 0.1; // Target used for init and normalization, the actual value does not really matter static constexpr const std::chrono::nanoseconds kDefaultTarget = 50ms; // Amount of time after the last message was sent before the session goes stale Loading services/surfaceflinger/SurfaceFlinger.cpp +17 −0 Original line number Diff line number Diff line Loading @@ -3603,6 +3603,23 @@ status_t SurfaceFlinger::addClientLayer(const sp<Client>& client, const sp<IBind if (mNumLayers >= ISurfaceComposer::MAX_LAYERS) { ALOGE("AddClientLayer failed, mNumLayers (%zu) >= MAX_LAYERS (%zu)", mNumLayers.load(), ISurfaceComposer::MAX_LAYERS); static_cast<void>(mScheduler->schedule([=] { ALOGE("Dumping random sampling of on-screen layers: "); mDrawingState.traverse([&](Layer *layer) { // Aim to dump about 200 layers to avoid totally trashing // logcat. On the other hand, if there really are 4096 layers // something has gone totally wrong its probably the most // useful information in logcat. if (rand() % 20 == 13) { ALOGE("Layer: %s", layer->getName().c_str()); } }); for (Layer* offscreenLayer : mOffscreenLayers) { if (rand() % 20 == 13) { ALOGE("Offscreen-layer: %s", offscreenLayer->getName().c_str()); } } })); return NO_MEMORY; } Loading services/surfaceflinger/tests/unittests/AidlPowerHalWrapperTest.cpp +46 −2 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ #undef LOG_TAG #define LOG_TAG "AidlPowerHalWrapperTest" #include <android-base/stringprintf.h> #include <android/hardware/power/IPower.h> #include <android/hardware/power/IPowerHintSession.h> #include <gmock/gmock.h> Loading Loading @@ -82,6 +83,15 @@ WorkDuration toWorkDuration(std::chrono::nanoseconds durationNanos, int64_t time return duration; } std::string printWorkDurations(const ::std::vector<WorkDuration>& durations) { std::ostringstream os; for (auto duration : durations) { os << duration.toString(); os << "\n"; } return os.str(); } namespace { TEST_F(AidlPowerHalWrapperTest, supportsPowerHintSession) { ASSERT_TRUE(mWrapper->supportsPowerHintSession()); Loading Loading @@ -143,8 +153,8 @@ TEST_F(AidlPowerHalWrapperTest, setTargetWorkDuration) { {-1ms, false}, {200ms, true}, {2ms, true}, {96ms, false}, {104ms, false}}; {91ms, false}, {109ms, false}}; for (const auto& test : testCases) { // reset to 100ms baseline Loading Loading @@ -212,6 +222,40 @@ TEST_F(AidlPowerHalWrapperTest, sendActualWorkDuration) { } } TEST_F(AidlPowerHalWrapperTest, sendAdjustedActualWorkDuration) { ASSERT_TRUE(mWrapper->supportsPowerHintSession()); std::vector<int32_t> threadIds = {1, 2}; mWrapper->setPowerHintSessionThreadIds(threadIds); EXPECT_CALL(*mMockHal.get(), createHintSession(_, _, threadIds, _, _)) .WillOnce(DoAll(SetArgPointee<4>(mMockSession), Return(Status::ok()))); ASSERT_TRUE(mWrapper->startPowerHintSession()); verifyAndClearExpectations(); std::chrono::nanoseconds lastTarget = 100ms; EXPECT_CALL(*mMockSession.get(), updateTargetWorkDuration(lastTarget.count())).Times(1); mWrapper->setTargetWorkDuration(lastTarget.count()); std::chrono::nanoseconds newTarget = 105ms; mWrapper->setTargetWorkDuration(newTarget.count()); EXPECT_CALL(*mMockSession.get(), updateTargetWorkDuration(newTarget.count())).Times(0); std::chrono::nanoseconds actual = 21ms; // 100 / 105 * 21ms = 20ms std::chrono::nanoseconds expectedActualSent = 20ms; std::vector<WorkDuration> expectedDurations = {toWorkDuration(expectedActualSent, 1)}; EXPECT_CALL(*mMockSession.get(), reportActualWorkDuration(_)) .WillOnce(DoAll( [expectedDurations](const ::std::vector<WorkDuration>& durationsSent) { EXPECT_EQ(expectedDurations, durationsSent) << base::StringPrintf("actual sent: %s vs expected: %s", printWorkDurations(durationsSent).c_str(), printWorkDurations(expectedDurations) .c_str()); }, Return(Status::ok()))); mWrapper->sendActualWorkDuration(actual.count(), 1); } TEST_F(AidlPowerHalWrapperTest, sendActualWorkDuration_exceedsStaleTime) { ASSERT_TRUE(mWrapper->supportsPowerHintSession()); Loading Loading
libs/binder/tests/parcel_fuzzer/Android.bp +2 −1 Original line number Diff line number Diff line Loading @@ -29,7 +29,6 @@ cc_fuzz { "libcutils", "libhidlbase", "liblog", "libutils", ], target: { Loading @@ -37,12 +36,14 @@ cc_fuzz { shared_libs: [ "libbinder_ndk", "libbinder", "libutils", ], }, host: { static_libs: [ "libbinder_ndk", "libbinder", "libutils", ], }, darwin: { Loading
services/surfaceflinger/DisplayHardware/PowerAdvisor.cpp +25 −13 Original line number Diff line number Diff line Loading @@ -463,29 +463,41 @@ void AidlPowerHalWrapper::sendActualWorkDuration(int64_t actualDurationNanos, ALOGV("Failed to send actual work duration, skipping"); return; } WorkDuration duration; duration.durationNanos = actualDurationNanos; mActualDuration = actualDurationNanos; nsecs_t reportedDuration = actualDurationNanos; // normalize the sent values to a pre-set target if (sNormalizeTarget) { duration.durationNanos += mLastTargetDurationSent - mTargetDuration; } reportedDuration += mLastTargetDurationSent - mTargetDuration; } else { // when target duration change is within deviation and not updated, adjust the actual // duration proportionally based on the difference, e.g. if new target is 5ms longer than // last reported but actual duration is the same as last target, we want to report a smaller // actual work duration now to indicate that we are overshooting if (mLastTargetDurationSent != kDefaultTarget.count() && mTargetDuration != 0) { reportedDuration = static_cast<int64_t>(static_cast<long double>(mLastTargetDurationSent) / mTargetDuration * actualDurationNanos); mActualDuration = reportedDuration; } } mActualDuration = reportedDuration; WorkDuration duration; duration.durationNanos = reportedDuration; duration.timeStampNanos = timeStampNanos; mPowerHintQueue.push_back(duration); nsecs_t targetNsec = mTargetDuration; nsecs_t durationNsec = actualDurationNanos; if (sTraceHintSessionData) { ATRACE_INT64("Measured duration", durationNsec); ATRACE_INT64("Target error term", targetNsec - durationNsec); ATRACE_INT64("Measured duration", actualDurationNanos); ATRACE_INT64("Target error term", mTargetDuration - actualDurationNanos); ATRACE_INT64("Reported duration", reportedDuration); ATRACE_INT64("Reported target", mLastTargetDurationSent); ATRACE_INT64("Reported target error term", mLastTargetDurationSent - reportedDuration); } ALOGV("Sending actual work duration of: %" PRId64 " on target: %" PRId64 ALOGV("Sending actual work duration of: %" PRId64 " on reported target: %" PRId64 " with error: %" PRId64, durationNsec, targetNsec, targetNsec - durationNsec); reportedDuration, mLastTargetDurationSent, mLastTargetDurationSent - reportedDuration); // This rate limiter queues similar duration reports to the powerhal into // batches to avoid excessive binder calls. The criteria to send a given batch Loading @@ -501,7 +513,7 @@ void AidlPowerHalWrapper::sendActualWorkDuration(int64_t actualDurationNanos, } mPowerHintQueue.clear(); // we save the non-normalized value here to detect % changes mLastActualDurationSent = actualDurationNanos; mLastActualDurationSent = reportedDuration; } } Loading
services/surfaceflinger/DisplayHardware/PowerAdvisor.h +2 −2 Original line number Diff line number Diff line Loading @@ -173,8 +173,8 @@ private: // Max percent the actual duration can vary without causing a report (eg: 0.1 = 10%) static constexpr double kAllowedActualDeviationPercent = 0.1; // Max percent the target duration can vary without causing a report (eg: 0.05 = 5%) static constexpr double kAllowedTargetDeviationPercent = 0.05; // Max percent the target duration can vary without causing a report (eg: 0.1 = 10%) static constexpr double kAllowedTargetDeviationPercent = 0.1; // Target used for init and normalization, the actual value does not really matter static constexpr const std::chrono::nanoseconds kDefaultTarget = 50ms; // Amount of time after the last message was sent before the session goes stale Loading
services/surfaceflinger/SurfaceFlinger.cpp +17 −0 Original line number Diff line number Diff line Loading @@ -3603,6 +3603,23 @@ status_t SurfaceFlinger::addClientLayer(const sp<Client>& client, const sp<IBind if (mNumLayers >= ISurfaceComposer::MAX_LAYERS) { ALOGE("AddClientLayer failed, mNumLayers (%zu) >= MAX_LAYERS (%zu)", mNumLayers.load(), ISurfaceComposer::MAX_LAYERS); static_cast<void>(mScheduler->schedule([=] { ALOGE("Dumping random sampling of on-screen layers: "); mDrawingState.traverse([&](Layer *layer) { // Aim to dump about 200 layers to avoid totally trashing // logcat. On the other hand, if there really are 4096 layers // something has gone totally wrong its probably the most // useful information in logcat. if (rand() % 20 == 13) { ALOGE("Layer: %s", layer->getName().c_str()); } }); for (Layer* offscreenLayer : mOffscreenLayers) { if (rand() % 20 == 13) { ALOGE("Offscreen-layer: %s", offscreenLayer->getName().c_str()); } } })); return NO_MEMORY; } Loading
services/surfaceflinger/tests/unittests/AidlPowerHalWrapperTest.cpp +46 −2 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ #undef LOG_TAG #define LOG_TAG "AidlPowerHalWrapperTest" #include <android-base/stringprintf.h> #include <android/hardware/power/IPower.h> #include <android/hardware/power/IPowerHintSession.h> #include <gmock/gmock.h> Loading Loading @@ -82,6 +83,15 @@ WorkDuration toWorkDuration(std::chrono::nanoseconds durationNanos, int64_t time return duration; } std::string printWorkDurations(const ::std::vector<WorkDuration>& durations) { std::ostringstream os; for (auto duration : durations) { os << duration.toString(); os << "\n"; } return os.str(); } namespace { TEST_F(AidlPowerHalWrapperTest, supportsPowerHintSession) { ASSERT_TRUE(mWrapper->supportsPowerHintSession()); Loading Loading @@ -143,8 +153,8 @@ TEST_F(AidlPowerHalWrapperTest, setTargetWorkDuration) { {-1ms, false}, {200ms, true}, {2ms, true}, {96ms, false}, {104ms, false}}; {91ms, false}, {109ms, false}}; for (const auto& test : testCases) { // reset to 100ms baseline Loading Loading @@ -212,6 +222,40 @@ TEST_F(AidlPowerHalWrapperTest, sendActualWorkDuration) { } } TEST_F(AidlPowerHalWrapperTest, sendAdjustedActualWorkDuration) { ASSERT_TRUE(mWrapper->supportsPowerHintSession()); std::vector<int32_t> threadIds = {1, 2}; mWrapper->setPowerHintSessionThreadIds(threadIds); EXPECT_CALL(*mMockHal.get(), createHintSession(_, _, threadIds, _, _)) .WillOnce(DoAll(SetArgPointee<4>(mMockSession), Return(Status::ok()))); ASSERT_TRUE(mWrapper->startPowerHintSession()); verifyAndClearExpectations(); std::chrono::nanoseconds lastTarget = 100ms; EXPECT_CALL(*mMockSession.get(), updateTargetWorkDuration(lastTarget.count())).Times(1); mWrapper->setTargetWorkDuration(lastTarget.count()); std::chrono::nanoseconds newTarget = 105ms; mWrapper->setTargetWorkDuration(newTarget.count()); EXPECT_CALL(*mMockSession.get(), updateTargetWorkDuration(newTarget.count())).Times(0); std::chrono::nanoseconds actual = 21ms; // 100 / 105 * 21ms = 20ms std::chrono::nanoseconds expectedActualSent = 20ms; std::vector<WorkDuration> expectedDurations = {toWorkDuration(expectedActualSent, 1)}; EXPECT_CALL(*mMockSession.get(), reportActualWorkDuration(_)) .WillOnce(DoAll( [expectedDurations](const ::std::vector<WorkDuration>& durationsSent) { EXPECT_EQ(expectedDurations, durationsSent) << base::StringPrintf("actual sent: %s vs expected: %s", printWorkDurations(durationsSent).c_str(), printWorkDurations(expectedDurations) .c_str()); }, Return(Status::ok()))); mWrapper->sendActualWorkDuration(actual.count(), 1); } TEST_F(AidlPowerHalWrapperTest, sendActualWorkDuration_exceedsStaleTime) { ASSERT_TRUE(mWrapper->supportsPowerHintSession()); Loading