Add test for setOverrideFrameRate
- Create test to verify the API call in SurfaceComposerClient
- Create test to verify frame rate override DisplayEventReceiver events
are correctly received
- Add permission AID_ROOT to setOverrideFrameRate
Bug: b/204322816
Test: atest Surfaceflinger_test
Change-Id: I5b1782fcb7fc4896139ad56fcaee61853480f153
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 73a5f58..5ca75d5 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -5520,7 +5520,13 @@
}
return PERMISSION_DENIED;
}
- case SET_OVERRIDE_FRAME_RATE:
+ case SET_OVERRIDE_FRAME_RATE: {
+ const int uid = IPCThreadState::self()->getCallingUid();
+ if (uid == AID_ROOT || uid == AID_SYSTEM) {
+ return OK;
+ }
+ return PERMISSION_DENIED;
+ }
case ON_PULL_ATOM: {
const int uid = IPCThreadState::self()->getCallingUid();
if (uid == AID_SYSTEM) {
diff --git a/services/surfaceflinger/tests/Android.bp b/services/surfaceflinger/tests/Android.bp
index 7b86229..c5c0c3f 100644
--- a/services/surfaceflinger/tests/Android.bp
+++ b/services/surfaceflinger/tests/Android.bp
@@ -47,6 +47,7 @@
"ReleaseBufferCallback_test.cpp",
"ScreenCapture_test.cpp",
"SetFrameRate_test.cpp",
+ "SetFrameRateOverride_test.cpp",
"SetGeometry_test.cpp",
"Stress_test.cpp",
"SurfaceInterceptor_test.cpp",
diff --git a/services/surfaceflinger/tests/SetFrameRateOverride_test.cpp b/services/surfaceflinger/tests/SetFrameRateOverride_test.cpp
new file mode 100644
index 0000000..4efec77
--- /dev/null
+++ b/services/surfaceflinger/tests/SetFrameRateOverride_test.cpp
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2022 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 <gtest/gtest.h>
+#include <gui/DisplayEventReceiver.h>
+#include <gui/ISurfaceComposer.h>
+#include <gui/SurfaceComposerClient.h>
+#include <sys/epoll.h>
+#include <algorithm>
+
+namespace android {
+namespace {
+using FrameRateOverride = DisplayEventReceiver::Event::FrameRateOverride;
+
+class SetFrameRateOverrideTest : public ::testing::Test {
+protected:
+ void SetUp() override {
+ const ISurfaceComposer::VsyncSource vsyncSource = ISurfaceComposer::eVsyncSourceApp;
+ const ISurfaceComposer::EventRegistrationFlags eventRegistration = {
+ ISurfaceComposer::EventRegistration::frameRateOverride};
+
+ mDisplayEventReceiver =
+ std::make_unique<DisplayEventReceiver>(vsyncSource, eventRegistration);
+ EXPECT_EQ(NO_ERROR, mDisplayEventReceiver->initCheck());
+
+ mEpollFd = epoll_create1(EPOLL_CLOEXEC);
+ EXPECT_GT(mEpollFd, 1);
+
+ epoll_event event;
+ event.events = EPOLLIN;
+ EXPECT_EQ(0, epoll_ctl(mEpollFd, EPOLL_CTL_ADD, mDisplayEventReceiver->getFd(), &event));
+ }
+
+ void TearDown() override { close(mEpollFd); }
+
+ void setFrameRateAndListenEvents(uid_t uid, float frameRate) {
+ status_t ret = SurfaceComposerClient::setOverrideFrameRate(uid, frameRate);
+ ASSERT_EQ(NO_ERROR, ret);
+
+ DisplayEventReceiver::Event event;
+ bool isOverrideFlushReceived = false;
+ mFrameRateOverrides.clear();
+
+ epoll_event epollEvent;
+ while (epoll_wait(mEpollFd, &epollEvent, 1, 1000) > 0) {
+ while (mDisplayEventReceiver->getEvents(&event, 1) > 0) {
+ if (event.header.type == DisplayEventReceiver::DISPLAY_EVENT_FRAME_RATE_OVERRIDE) {
+ mFrameRateOverrides.emplace_back(event.frameRateOverride);
+ }
+ if (event.header.type ==
+ DisplayEventReceiver::DISPLAY_EVENT_FRAME_RATE_OVERRIDE_FLUSH) {
+ isOverrideFlushReceived = true;
+ }
+ }
+
+ if (isOverrideFlushReceived) break;
+ }
+ }
+
+ std::unique_ptr<DisplayEventReceiver> mDisplayEventReceiver;
+ std::vector<FrameRateOverride> mFrameRateOverrides;
+
+ int mEpollFd;
+};
+
+TEST_F(SetFrameRateOverrideTest, SetFrameRateOverrideCall) {
+ uid_t uid = getuid();
+ float frameRate = 30.0f;
+ setFrameRateAndListenEvents(uid, frameRate);
+ // check if the frame rate override we set exists
+ ASSERT_TRUE(std::find_if(mFrameRateOverrides.begin(), mFrameRateOverrides.end(),
+ [uid = uid, frameRate = frameRate](auto i) {
+ return uid == i.uid && frameRate == i.frameRateHz;
+ }) != mFrameRateOverrides.end());
+
+ // test removing frame rate override
+ frameRate = 0.0f;
+ setFrameRateAndListenEvents(uid, frameRate);
+ ASSERT_TRUE(std::find_if(mFrameRateOverrides.begin(), mFrameRateOverrides.end(),
+ [uid = uid, frameRate = frameRate](auto i) {
+ return uid == i.uid && frameRate == i.frameRateHz;
+ }) == mFrameRateOverrides.end());
+}
+} // namespace
+} // namespace android