diff options
author | 2023-09-27 19:15:08 -0700 | |
---|---|---|
committer | 2023-10-02 19:03:52 +0000 | |
commit | 07d03c4d260b804c07f7ac927515b26c84c9a4ea (patch) | |
tree | b0063a63627e1f66177597807523035c4bc4698d | |
parent | aefb330cc0317bdd18d5bbc5ea51cf00ecabf66b (diff) |
SF: fix binder thread priority
Add setMinSchedulerPolicy to all binder interfaces SF exposes.
It was missing from gui::ISurfaceComposer and
gui::IDisplayEventConnection.
Test: presubmit
Bug: 299378819
Change-Id: Ia0d99efa5a3bc58625c320d4df3c08bb597d2e38
19 files changed, 360 insertions, 5 deletions
diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp index b526a6c92c..ff6b558d41 100644 --- a/libs/gui/ISurfaceComposer.cpp +++ b/libs/gui/ISurfaceComposer.cpp @@ -25,6 +25,7 @@ #include <gui/IGraphicBufferProducer.h> #include <gui/ISurfaceComposer.h> #include <gui/LayerState.h> +#include <gui/SchedulingPolicy.h> #include <private/gui/ParcelUtils.h> #include <stdint.h> #include <sys/types.h> @@ -201,6 +202,18 @@ status_t BnSurfaceComposer::onTransact( isAutoTimestamp, uncacheBuffers, hasListenerCallbacks, listenerCallbacks, transactionId, mergedTransactions); } + case GET_SCHEDULING_POLICY: { + gui::SchedulingPolicy policy; + const auto status = gui::getSchedulingPolicy(&policy); + if (!status.isOk()) { + return status.exceptionCode(); + } + + SAFE_PARCEL(reply->writeInt32, policy.policy); + SAFE_PARCEL(reply->writeInt32, policy.priority); + return NO_ERROR; + } + default: { return BBinder::onTransact(code, data, reply, flags); } diff --git a/libs/gui/aidl/android/gui/IDisplayEventConnection.aidl b/libs/gui/aidl/android/gui/IDisplayEventConnection.aidl index 9781ca96f4..008ef19244 100644 --- a/libs/gui/aidl/android/gui/IDisplayEventConnection.aidl +++ b/libs/gui/aidl/android/gui/IDisplayEventConnection.aidl @@ -18,6 +18,7 @@ package android.gui; import android.gui.BitTube; import android.gui.ParcelableVsyncEventData; +import android.gui.SchedulingPolicy; /** @hide */ interface IDisplayEventConnection { @@ -44,4 +45,9 @@ interface IDisplayEventConnection { * getLatestVsyncEventData() gets the latest vsync event data. */ ParcelableVsyncEventData getLatestVsyncEventData(); + + /* + * getSchedulingPolicy() used in tests to validate the binder thread pririty + */ + SchedulingPolicy getSchedulingPolicy(); } diff --git a/libs/gui/aidl/android/gui/ISurfaceComposer.aidl b/libs/gui/aidl/android/gui/ISurfaceComposer.aidl index 1c604a1f8b..507e0868d7 100644 --- a/libs/gui/aidl/android/gui/ISurfaceComposer.aidl +++ b/libs/gui/aidl/android/gui/ISurfaceComposer.aidl @@ -46,6 +46,7 @@ import android.gui.LayerDebugInfo; import android.gui.OverlayProperties; import android.gui.PullAtomData; import android.gui.ARect; +import android.gui.SchedulingPolicy; import android.gui.StalledTransactionInfo; import android.gui.StaticDisplayInfo; import android.gui.WindowInfosListenerInfo; @@ -545,4 +546,6 @@ interface ISurfaceComposer { * applied in SurfaceFlinger due to an unsignaled fence. Otherwise, null is returned. */ @nullable StalledTransactionInfo getStalledTransactionInfo(int pid); + + SchedulingPolicy getSchedulingPolicy(); } diff --git a/libs/gui/aidl/android/gui/ISurfaceComposerClient.aidl b/libs/gui/aidl/android/gui/ISurfaceComposerClient.aidl index 68781ce953..920257c449 100644 --- a/libs/gui/aidl/android/gui/ISurfaceComposerClient.aidl +++ b/libs/gui/aidl/android/gui/ISurfaceComposerClient.aidl @@ -19,6 +19,7 @@ package android.gui; import android.gui.CreateSurfaceResult; import android.gui.FrameStats; import android.gui.LayerMetadata; +import android.gui.SchedulingPolicy; /** @hide */ interface ISurfaceComposerClient { @@ -60,4 +61,6 @@ interface ISurfaceComposerClient { CreateSurfaceResult mirrorSurface(IBinder mirrorFromHandle); CreateSurfaceResult mirrorDisplay(long displayId); + + SchedulingPolicy getSchedulingPolicy(); } diff --git a/libs/gui/aidl/android/gui/SchedulingPolicy.aidl b/libs/gui/aidl/android/gui/SchedulingPolicy.aidl new file mode 100644 index 0000000000..4f7cf0a493 --- /dev/null +++ b/libs/gui/aidl/android/gui/SchedulingPolicy.aidl @@ -0,0 +1,23 @@ +/* + * Copyright 2023 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. + */ + +package android.gui; + +/** @hide */ +parcelable SchedulingPolicy { + int policy; + int priority; +} diff --git a/libs/gui/fuzzer/libgui_fuzzer_utils.h b/libs/gui/fuzzer/libgui_fuzzer_utils.h index bdf8856a75..3142103d17 100644 --- a/libs/gui/fuzzer/libgui_fuzzer_utils.h +++ b/libs/gui/fuzzer/libgui_fuzzer_utils.h @@ -166,6 +166,7 @@ public: MOCK_METHOD(binder::Status, getOverlaySupport, (gui::OverlayProperties*), (override)); MOCK_METHOD(binder::Status, getStalledTransactionInfo, (int32_t, std::optional<gui::StalledTransactionInfo>*), (override)); + MOCK_METHOD(binder::Status, getSchedulingPolicy, (gui::SchedulingPolicy*), (override)); }; class FakeBnSurfaceComposerClient : public gui::BnSurfaceComposerClient { @@ -186,6 +187,8 @@ public: MOCK_METHOD(binder::Status, mirrorDisplay, (int64_t displayId, gui::CreateSurfaceResult* outResult), (override)); + + MOCK_METHOD(binder::Status, getSchedulingPolicy, (gui::SchedulingPolicy*), (override)); }; class FakeDisplayEventDispatcher : public DisplayEventDispatcher { diff --git a/libs/gui/include/gui/ISurfaceComposer.h b/libs/gui/include/gui/ISurfaceComposer.h index 3ff6735926..a836f4642a 100644 --- a/libs/gui/include/gui/ISurfaceComposer.h +++ b/libs/gui/include/gui/ISurfaceComposer.h @@ -199,6 +199,7 @@ public: SET_BOOT_DISPLAY_MODE, // Deprecated. Autogenerated by .aidl now. CLEAR_BOOT_DISPLAY_MODE, // Deprecated. Autogenerated by .aidl now. SET_OVERRIDE_FRAME_RATE, // Deprecated. Autogenerated by .aidl now. + GET_SCHEDULING_POLICY, // Always append new enum to the end. }; diff --git a/libs/gui/include/gui/SchedulingPolicy.h b/libs/gui/include/gui/SchedulingPolicy.h new file mode 100644 index 0000000000..48c9f0c7bf --- /dev/null +++ b/libs/gui/include/gui/SchedulingPolicy.h @@ -0,0 +1,40 @@ +/* + * Copyright 2023 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. + */ + +#pragma once + +#include <sched.h> + +#include <android/gui/SchedulingPolicy.h> +#include <binder/Status.h> + +namespace android::gui { + +static binder::Status getSchedulingPolicy(gui::SchedulingPolicy* outPolicy) { + outPolicy->policy = sched_getscheduler(0); + if (outPolicy->policy < 0) { + return binder::Status::fromExceptionCode(EX_ILLEGAL_STATE); + } + + struct sched_param param; + if (sched_getparam(0, ¶m) < 0) { + return binder::Status::fromExceptionCode(EX_ILLEGAL_STATE); + } + outPolicy->priority = param.sched_priority; + return binder::Status::ok(); +} + +} // namespace android::gui
\ No newline at end of file diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp index daed764cd6..9eee699f23 100644 --- a/libs/gui/tests/Surface_test.cpp +++ b/libs/gui/tests/Surface_test.cpp @@ -1036,6 +1036,10 @@ public: return binder::Status::ok(); } + binder::Status getSchedulingPolicy(gui::SchedulingPolicy*) override { + return binder::Status::ok(); + } + protected: IBinder* onAsBinder() override { return nullptr; } diff --git a/services/surfaceflinger/Client.cpp b/services/surfaceflinger/Client.cpp index bdbc79b8e1..6b4215e2f4 100644 --- a/services/surfaceflinger/Client.cpp +++ b/services/surfaceflinger/Client.cpp @@ -22,6 +22,7 @@ #include <private/android_filesystem_config.h> #include <gui/AidlStatusUtil.h> +#include <gui/SchedulingPolicy.h> #include "Client.h" #include "FrontEnd/LayerCreationArgs.h" @@ -117,5 +118,9 @@ binder::Status Client::mirrorDisplay(int64_t displayId, gui::CreateSurfaceResult return binderStatusFromStatusT(status); } +binder::Status Client::getSchedulingPolicy(gui::SchedulingPolicy* outPolicy) { + return gui::getSchedulingPolicy(outPolicy); +} + // --------------------------------------------------------------------------- }; // namespace android diff --git a/services/surfaceflinger/Client.h b/services/surfaceflinger/Client.h index af410ea19c..77916e0a78 100644 --- a/services/surfaceflinger/Client.h +++ b/services/surfaceflinger/Client.h @@ -55,6 +55,8 @@ private: binder::Status mirrorDisplay(int64_t displayId, gui::CreateSurfaceResult* outResult) override; + binder::Status getSchedulingPolicy(gui::SchedulingPolicy* outPolicy) override; + // constant sp<SurfaceFlinger> mFlinger; diff --git a/services/surfaceflinger/Scheduler/EventThread.cpp b/services/surfaceflinger/Scheduler/EventThread.cpp index edab7ecee1..9a55c94424 100644 --- a/services/surfaceflinger/Scheduler/EventThread.cpp +++ b/services/surfaceflinger/Scheduler/EventThread.cpp @@ -38,6 +38,7 @@ #include <cutils/sched_policy.h> #include <gui/DisplayEventReceiver.h> +#include <gui/SchedulingPolicy.h> #include <utils/Errors.h> #include <utils/Trace.h> @@ -218,6 +219,10 @@ binder::Status EventThreadConnection::getLatestVsyncEventData( return binder::Status::ok(); } +binder::Status EventThreadConnection::getSchedulingPolicy(gui::SchedulingPolicy* outPolicy) { + return gui::getSchedulingPolicy(outPolicy); +} + status_t EventThreadConnection::postEvent(const DisplayEventReceiver::Event& event) { constexpr auto toStatus = [](ssize_t size) { return size < 0 ? status_t(size) : status_t(NO_ERROR); @@ -300,9 +305,14 @@ void EventThread::setDuration(std::chrono::nanoseconds workDuration, sp<EventThreadConnection> EventThread::createEventConnection( EventRegistrationFlags eventRegistration) const { - return sp<EventThreadConnection>::make(const_cast<EventThread*>(this), - IPCThreadState::self()->getCallingUid(), - eventRegistration); + auto connection = sp<EventThreadConnection>::make(const_cast<EventThread*>(this), + IPCThreadState::self()->getCallingUid(), + eventRegistration); + if (flags::misc1()) { + const int policy = SCHED_FIFO; + connection->setMinSchedulerPolicy(policy, sched_get_priority_min(policy)); + } + return connection; } status_t EventThread::registerDisplayEventConnection(const sp<EventThreadConnection>& connection) { diff --git a/services/surfaceflinger/Scheduler/EventThread.h b/services/surfaceflinger/Scheduler/EventThread.h index a7c8b74b91..7842318e2e 100644 --- a/services/surfaceflinger/Scheduler/EventThread.h +++ b/services/surfaceflinger/Scheduler/EventThread.h @@ -78,6 +78,7 @@ public: binder::Status setVsyncRate(int rate) override; binder::Status requestNextVsync() override; // asynchronous binder::Status getLatestVsyncEventData(ParcelableVsyncEventData* outVsyncEventData) override; + binder::Status getSchedulingPolicy(gui::SchedulingPolicy* outPolicy) override; VSyncRequest vsyncRequest = VSyncRequest::None; const uid_t mOwnerUid; diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 12aacad64c..3f52444c40 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -113,6 +113,7 @@ #include <vector> #include <gui/LayerStatePermissions.h> +#include <gui/SchedulingPolicy.h> #include <ui/DisplayIdentification.h> #include "BackgroundExecutor.h" #include "Client.h" @@ -6579,6 +6580,7 @@ status_t SurfaceFlinger::CheckTransactCodeCredentials(uint32_t code) { case GET_ACTIVE_DISPLAY_MODE: case GET_DISPLAY_COLOR_MODES: case GET_DISPLAY_MODES: + case GET_SCHEDULING_POLICY: // Calling setTransactionState is safe, because you need to have been // granted a reference to Client* and Handle* to do anything with it. case SET_TRANSACTION_STATE: { @@ -9016,6 +9018,10 @@ binder::Status SurfaceComposerAIDL::createConnection(sp<gui::ISurfaceComposerCli const sp<Client> client = sp<Client>::make(mFlinger); if (client->initCheck() == NO_ERROR) { *outClient = client; + if (flags::misc1()) { + const int policy = SCHED_FIFO; + client->setMinSchedulerPolicy(policy, sched_get_priority_min(policy)); + } return binder::Status::ok(); } else { *outClient = nullptr; @@ -9797,6 +9803,10 @@ binder::Status SurfaceComposerAIDL::getStalledTransactionInfo( return binderStatusFromStatusT(status); } +binder::Status SurfaceComposerAIDL::getSchedulingPolicy(gui::SchedulingPolicy* outPolicy) { + return gui::getSchedulingPolicy(outPolicy); +} + status_t SurfaceComposerAIDL::checkAccessPermission(bool usePermissionCache) { if (!mFlinger->callingThreadHasUnscopedSurfaceFlingerAccess(usePermissionCache)) { IPCThreadState* ipc = IPCThreadState::self(); diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index 42825f77fc..a5a2341b14 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -1581,8 +1581,9 @@ public: gui::WindowInfosListenerInfo* outInfo) override; binder::Status removeWindowInfosListener( const sp<gui::IWindowInfosListener>& windowInfosListener) override; - binder::Status getStalledTransactionInfo(int pid, - std::optional<gui::StalledTransactionInfo>* outInfo); + binder::Status getStalledTransactionInfo( + int pid, std::optional<gui::StalledTransactionInfo>* outInfo) override; + binder::Status getSchedulingPolicy(gui::SchedulingPolicy* outPolicy) override; private: static const constexpr bool kUsePermissionCache = true; diff --git a/services/surfaceflinger/fuzzer/surfaceflinger_fuzzer.cpp b/services/surfaceflinger/fuzzer/surfaceflinger_fuzzer.cpp index ed8bb7fc93..d13189e439 100644 --- a/services/surfaceflinger/fuzzer/surfaceflinger_fuzzer.cpp +++ b/services/surfaceflinger/fuzzer/surfaceflinger_fuzzer.cpp @@ -94,6 +94,7 @@ static constexpr BnSurfaceComposer::ISurfaceComposerTag kSurfaceComposerTags[]{ BnSurfaceComposer::REMOVE_TUNNEL_MODE_ENABLED_LISTENER, BnSurfaceComposer::ADD_WINDOW_INFOS_LISTENER, BnSurfaceComposer::REMOVE_WINDOW_INFOS_LISTENER, + BnSurfaceComposer::GET_SCHEDULING_POLICY, }; static constexpr uint32_t kMinCode = 1000; diff --git a/services/surfaceflinger/main_surfaceflinger.cpp b/services/surfaceflinger/main_surfaceflinger.cpp index cf23169eae..959945230d 100644 --- a/services/surfaceflinger/main_surfaceflinger.cpp +++ b/services/surfaceflinger/main_surfaceflinger.cpp @@ -149,6 +149,9 @@ int main(int, char**) { // publish gui::ISurfaceComposer, the new AIDL interface sp<SurfaceComposerAIDL> composerAIDL = sp<SurfaceComposerAIDL>::make(flinger); + if (flags::misc1()) { + composerAIDL->setMinSchedulerPolicy(SCHED_FIFO, newPriority); + } sm->addService(String16("SurfaceFlingerAIDL"), composerAIDL, false, IServiceManager::DUMP_FLAG_PRIORITY_CRITICAL | IServiceManager::DUMP_FLAG_PROTO); diff --git a/services/surfaceflinger/tests/Android.bp b/services/surfaceflinger/tests/Android.bp index b5168b0f01..36b197234a 100644 --- a/services/surfaceflinger/tests/Android.bp +++ b/services/surfaceflinger/tests/Android.bp @@ -30,6 +30,7 @@ cc_test { test_suites: ["device-tests"], srcs: [ "BootDisplayMode_test.cpp", + "Binder_test.cpp", "BufferGenerator.cpp", "CommonTypes_test.cpp", "Credentials_test.cpp", diff --git a/services/surfaceflinger/tests/Binder_test.cpp b/services/surfaceflinger/tests/Binder_test.cpp new file mode 100644 index 0000000000..3152973da6 --- /dev/null +++ b/services/surfaceflinger/tests/Binder_test.cpp @@ -0,0 +1,225 @@ +/* + * Copyright 2023 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 <errno.h> +#include <sched.h> + +#include <android/gui/ISurfaceComposer.h> +#include <android/gui/ISurfaceComposerClient.h> +#include <binder/IBinder.h> +#include <binder/IServiceManager.h> +#include <gtest/gtest.h> +#include <gui/ISurfaceComposer.h> + +#include <com_android_graphics_surfaceflinger_flags.h> + +namespace android::test { +using namespace com::android::graphics::surfaceflinger; + +class BinderTest : public ::testing::Test { +protected: + BinderTest(); + + void SetUp() override; + + void getSchedulingPolicy(gui::SchedulingPolicy* outPolicy); + void getNonAidlSchedulingPolicy(gui::SchedulingPolicy* outPolicy); + void getClientSchedulingPolicy(gui::SchedulingPolicy* outPolicy); + void getDisplayEventConnectionSchedulingPolicy(gui::SchedulingPolicy* outPolicy); + +private: + sp<gui::ISurfaceComposer> mISurfaceComposerAidl; + sp<ISurfaceComposer> mISurfaceComposer; + sp<gui::ISurfaceComposerClient> mISurfaceComposerClient; + sp<gui::IDisplayEventConnection> mConnection; +}; + +BinderTest::BinderTest() { + const String16 name("SurfaceFlingerAIDL"); + mISurfaceComposerAidl = waitForService<gui::ISurfaceComposer>(String16("SurfaceFlingerAIDL")); + mISurfaceComposer = waitForService<ISurfaceComposer>(String16("SurfaceFlinger")); + mISurfaceComposerAidl->createConnection(&mISurfaceComposerClient); + mISurfaceComposerAidl + ->createDisplayEventConnection(gui::ISurfaceComposer::VsyncSource::eVsyncSourceApp, + gui::ISurfaceComposer::EventRegistration(0), {}, + &mConnection); +} + +void BinderTest::SetUp() { + ASSERT_TRUE(mISurfaceComposerAidl); + ASSERT_TRUE(mISurfaceComposer); + ASSERT_TRUE(mISurfaceComposerClient); + ASSERT_TRUE(mConnection); +} + +void BinderTest::getSchedulingPolicy(gui::SchedulingPolicy* outPolicy) { + const auto status = mISurfaceComposerAidl->getSchedulingPolicy(outPolicy); + ASSERT_TRUE(status.isOk()); +} + +void BinderTest::getNonAidlSchedulingPolicy(gui::SchedulingPolicy* outPolicy) { + Parcel data, reply; + const status_t status = + IInterface::asBinder(mISurfaceComposer) + ->transact(BnSurfaceComposer::GET_SCHEDULING_POLICY, data, &reply); + ASSERT_EQ(OK, status); + + outPolicy->policy = reply.readInt32(); + outPolicy->priority = reply.readInt32(); +} + +void BinderTest::getClientSchedulingPolicy(gui::SchedulingPolicy* outPolicy) { + const auto status = mISurfaceComposerClient->getSchedulingPolicy(outPolicy); + ASSERT_TRUE(status.isOk()); +} + +void BinderTest::getDisplayEventConnectionSchedulingPolicy(gui::SchedulingPolicy* outPolicy) { + const auto status = mConnection->getSchedulingPolicy(outPolicy); + ASSERT_TRUE(status.isOk()); +} + +TEST_F(BinderTest, SchedulingPolicy) { + if (!flags::misc1()) GTEST_SKIP(); + + const int policy = SCHED_FIFO; + const int priority = sched_get_priority_min(policy); + + gui::SchedulingPolicy sfPolicy; + ASSERT_NO_FATAL_FAILURE(getSchedulingPolicy(&sfPolicy)); + + ASSERT_EQ(policy, sfPolicy.policy & (~SCHED_RESET_ON_FORK)); + ASSERT_EQ(priority, sfPolicy.priority); +} + +TEST_F(BinderTest, NonAidlSchedulingPolicy) { + const int policy = SCHED_FIFO; + const int priority = sched_get_priority_min(policy); + + gui::SchedulingPolicy sfPolicy; + ASSERT_NO_FATAL_FAILURE(getNonAidlSchedulingPolicy(&sfPolicy)); + + ASSERT_EQ(policy, sfPolicy.policy & (~SCHED_RESET_ON_FORK)); + ASSERT_EQ(priority, sfPolicy.priority); +} + +TEST_F(BinderTest, ClientSchedulingPolicy) { + if (!flags::misc1()) GTEST_SKIP(); + + const int policy = SCHED_FIFO; + const int priority = sched_get_priority_min(policy); + + gui::SchedulingPolicy sfPolicy; + ASSERT_NO_FATAL_FAILURE(getClientSchedulingPolicy(&sfPolicy)); + + ASSERT_EQ(policy, sfPolicy.policy & (~SCHED_RESET_ON_FORK)); + ASSERT_EQ(priority, sfPolicy.priority); +} + +TEST_F(BinderTest, DisplayEventConnectionSchedulingPolicy) { + if (!flags::misc1()) GTEST_SKIP(); + + const int policy = SCHED_FIFO; + const int priority = sched_get_priority_min(policy); + + gui::SchedulingPolicy sfPolicy; + ASSERT_NO_FATAL_FAILURE(getDisplayEventConnectionSchedulingPolicy(&sfPolicy)); + + ASSERT_EQ(policy, sfPolicy.policy & (~SCHED_RESET_ON_FORK)); + ASSERT_EQ(priority, sfPolicy.priority); +} + +class BinderTestRtCaller : public BinderTest { +protected: + void SetUp() override; + void TearDown() override; + +private: + int mOrigPolicy; + int mOrigPriority; +}; + +void BinderTestRtCaller::SetUp() { + const int policy = SCHED_FIFO; + const int priority = sched_get_priority_min(policy); + + mOrigPolicy = sched_getscheduler(0); + struct sched_param origSchedParam; + ASSERT_GE(0, sched_getparam(0, &origSchedParam)) << "errno: " << strerror(errno); + mOrigPriority = origSchedParam.sched_priority; + + struct sched_param param; + param.sched_priority = priority; + ASSERT_GE(0, sched_setscheduler(0, policy, ¶m)) << "errno: " << strerror(errno); +} + +void BinderTestRtCaller::TearDown() { + struct sched_param origSchedParam; + origSchedParam.sched_priority = mOrigPriority; + ASSERT_GE(0, sched_setscheduler(0, mOrigPolicy, &origSchedParam)) + << "errno: " << strerror(errno); +} + +TEST_F(BinderTestRtCaller, SchedulingPolicy) { + if (!flags::misc1()) GTEST_SKIP(); + + const int policy = SCHED_FIFO; + const int priority = sched_get_priority_min(policy); + + gui::SchedulingPolicy sfPolicy; + ASSERT_NO_FATAL_FAILURE(getSchedulingPolicy(&sfPolicy)); + + ASSERT_EQ(policy, sfPolicy.policy & (~SCHED_RESET_ON_FORK)); + ASSERT_EQ(priority, sfPolicy.priority); +} + +TEST_F(BinderTestRtCaller, NonAidlSchedulingPolicy) { + const int policy = SCHED_FIFO; + const int priority = sched_get_priority_min(policy); + + gui::SchedulingPolicy sfPolicy; + ASSERT_NO_FATAL_FAILURE(getNonAidlSchedulingPolicy(&sfPolicy)); + + ASSERT_EQ(policy, sfPolicy.policy & (~SCHED_RESET_ON_FORK)); + ASSERT_EQ(priority, sfPolicy.priority); +} + +TEST_F(BinderTestRtCaller, ClientSchedulingPolicy) { + if (!flags::misc1()) GTEST_SKIP(); + + const int policy = SCHED_FIFO; + const int priority = sched_get_priority_min(policy); + + gui::SchedulingPolicy sfPolicy; + ASSERT_NO_FATAL_FAILURE(getClientSchedulingPolicy(&sfPolicy)); + + ASSERT_EQ(policy, sfPolicy.policy & (~SCHED_RESET_ON_FORK)); + ASSERT_EQ(priority, sfPolicy.priority); +} + +TEST_F(BinderTestRtCaller, DisplayEventConnectionSchedulingPolicy) { + if (!flags::misc1()) GTEST_SKIP(); + + const int policy = SCHED_FIFO; + const int priority = sched_get_priority_min(policy); + + gui::SchedulingPolicy sfPolicy; + ASSERT_NO_FATAL_FAILURE(getDisplayEventConnectionSchedulingPolicy(&sfPolicy)); + + ASSERT_EQ(policy, sfPolicy.policy & (~SCHED_RESET_ON_FORK)); + ASSERT_EQ(priority, sfPolicy.priority); +} + +} // namespace android::test |