SurfaceFlinger: add explicit register for DISPLAY_EVENT_CONFIG_CHANGED

When display refresh rate changes, SF fires DISPLAY_EVENT_CONFIG_CHANGED
thru DisplayEventReceiver. If the other end of the pipe doesn't consume
the events it may lead to pipe full and dropping of events. Furthermore,
The only clients interested in this event in DisplayManager and hwui.

To avoid spamming all clients with this event, this change is adding an
explicit register for DISPLAY_EVENT_CONFIG_CHANGED events.

Bug: 131688378
Test: adb shell /data/nativetest64/libsurfaceflinger_unittest/libsurfaceflinger_unittest
Test: trigger config change and observe logcat
Change-Id: I5973a1ecc1f3e3ff8d8a0cba19db0e49ef0d5341
diff --git a/libs/gui/DisplayEventReceiver.cpp b/libs/gui/DisplayEventReceiver.cpp
index f5cf1c4..b8faa2d 100644
--- a/libs/gui/DisplayEventReceiver.cpp
+++ b/libs/gui/DisplayEventReceiver.cpp
@@ -32,10 +32,11 @@
 
 // ---------------------------------------------------------------------------
 
-DisplayEventReceiver::DisplayEventReceiver(ISurfaceComposer::VsyncSource vsyncSource) {
+DisplayEventReceiver::DisplayEventReceiver(ISurfaceComposer::VsyncSource vsyncSource,
+                                           ISurfaceComposer::ConfigChanged configChanged) {
     sp<ISurfaceComposer> sf(ComposerService::getComposerService());
     if (sf != nullptr) {
-        mEventConnection = sf->createDisplayEventConnection(vsyncSource);
+        mEventConnection = sf->createDisplayEventConnection(vsyncSource, configChanged);
         if (mEventConnection != nullptr) {
             mDataChannel = std::make_unique<gui::BitTube>();
             mEventConnection->stealReceiveChannel(mDataChannel.get());
diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp
index 6c9d81a..e487792 100644
--- a/libs/gui/ISurfaceComposer.cpp
+++ b/libs/gui/ISurfaceComposer.cpp
@@ -278,8 +278,8 @@
         return NO_ERROR;
     }
 
-    virtual sp<IDisplayEventConnection> createDisplayEventConnection(VsyncSource vsyncSource)
-    {
+    virtual sp<IDisplayEventConnection> createDisplayEventConnection(VsyncSource vsyncSource,
+                                                                     ConfigChanged configChanged) {
         Parcel data, reply;
         sp<IDisplayEventConnection> result;
         int err = data.writeInterfaceToken(
@@ -288,6 +288,7 @@
             return result;
         }
         data.writeInt32(static_cast<int32_t>(vsyncSource));
+        data.writeInt32(static_cast<int32_t>(configChanged));
         err = remote()->transact(
                 BnSurfaceComposer::CREATE_DISPLAY_EVENT_CONNECTION,
                 data, &reply);
@@ -1155,8 +1156,11 @@
         }
         case CREATE_DISPLAY_EVENT_CONNECTION: {
             CHECK_INTERFACE(ISurfaceComposer, data, reply);
-            sp<IDisplayEventConnection> connection(createDisplayEventConnection(
-                    static_cast<ISurfaceComposer::VsyncSource>(data.readInt32())));
+            auto vsyncSource = static_cast<ISurfaceComposer::VsyncSource>(data.readInt32());
+            auto configChanged = static_cast<ISurfaceComposer::ConfigChanged>(data.readInt32());
+
+            sp<IDisplayEventConnection> connection(
+                    createDisplayEventConnection(vsyncSource, configChanged));
             reply->writeStrongBinder(IInterface::asBinder(connection));
             return NO_ERROR;
         }
diff --git a/libs/gui/include/gui/DisplayEventReceiver.h b/libs/gui/include/gui/DisplayEventReceiver.h
index 22de751..a558cf9 100644
--- a/libs/gui/include/gui/DisplayEventReceiver.h
+++ b/libs/gui/include/gui/DisplayEventReceiver.h
@@ -88,10 +88,13 @@
      * DisplayEventReceiver creates and registers an event connection with
      * SurfaceFlinger. VSync events are disabled by default. Call setVSyncRate
      * or requestNextVsync to receive them.
+     * To receive Config Changed events specify this in the constructor.
      * Other events start being delivered immediately.
      */
     explicit DisplayEventReceiver(
-            ISurfaceComposer::VsyncSource vsyncSource = ISurfaceComposer::eVsyncSourceApp);
+            ISurfaceComposer::VsyncSource vsyncSource = ISurfaceComposer::eVsyncSourceApp,
+            ISurfaceComposer::ConfigChanged configChanged =
+                    ISurfaceComposer::eConfigChangedSuppress);
 
     /*
      * ~DisplayEventReceiver severs the connection with SurfaceFlinger, new events
diff --git a/libs/gui/include/gui/ISurfaceComposer.h b/libs/gui/include/gui/ISurfaceComposer.h
index e2f7736..c84910b 100644
--- a/libs/gui/include/gui/ISurfaceComposer.h
+++ b/libs/gui/include/gui/ISurfaceComposer.h
@@ -90,6 +90,8 @@
         eVsyncSourceSurfaceFlinger = 1
     };
 
+    enum ConfigChanged { eConfigChangedSuppress = 0, eConfigChangedDispatch = 1 };
+
     /*
      * Create a connection with SurfaceFlinger.
      */
@@ -97,7 +99,8 @@
 
     /* return an IDisplayEventConnection */
     virtual sp<IDisplayEventConnection> createDisplayEventConnection(
-            VsyncSource vsyncSource = eVsyncSourceApp) = 0;
+            VsyncSource vsyncSource = eVsyncSourceApp,
+            ConfigChanged configChanged = eConfigChangedSuppress) = 0;
 
     /* create a virtual display
      * requires ACCESS_SURFACE_FLINGER permission.
diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp
index 960cf18..d370858 100644
--- a/libs/gui/tests/Surface_test.cpp
+++ b/libs/gui/tests/Surface_test.cpp
@@ -548,8 +548,8 @@
     }
 
     sp<ISurfaceComposerClient> createConnection() override { return nullptr; }
-    sp<IDisplayEventConnection> createDisplayEventConnection(ISurfaceComposer::VsyncSource)
-            override {
+    sp<IDisplayEventConnection> createDisplayEventConnection(
+            ISurfaceComposer::VsyncSource, ISurfaceComposer::ConfigChanged) override {
         return nullptr;
     }
     sp<IBinder> createDisplay(const String8& /*displayName*/,
diff --git a/services/surfaceflinger/Scheduler/EventThread.cpp b/services/surfaceflinger/Scheduler/EventThread.cpp
index 05bad4d..9d1f777 100644
--- a/services/surfaceflinger/Scheduler/EventThread.cpp
+++ b/services/surfaceflinger/Scheduler/EventThread.cpp
@@ -76,6 +76,10 @@
             return StringPrintf("VSync{displayId=%" ANDROID_PHYSICAL_DISPLAY_ID_FORMAT
                                 ", count=%u}",
                                 event.header.displayId, event.vsync.count);
+        case DisplayEventReceiver::DISPLAY_EVENT_CONFIG_CHANGED:
+            return StringPrintf("ConfigChanged{displayId=%" ANDROID_PHYSICAL_DISPLAY_ID_FORMAT
+                                ", configId=%u}",
+                                event.header.displayId, event.config.configId);
         default:
             return "Event{}";
     }
@@ -107,8 +111,10 @@
 } // namespace
 
 EventThreadConnection::EventThreadConnection(EventThread* eventThread,
-                                             ResyncCallback resyncCallback)
+                                             ResyncCallback resyncCallback,
+                                             ISurfaceComposer::ConfigChanged configChanged)
       : resyncCallback(std::move(resyncCallback)),
+        configChanged(configChanged),
         mEventThread(eventThread),
         mChannel(gui::BitTube::DefaultSize) {}
 
@@ -203,8 +209,10 @@
     mVSyncSource->setPhaseOffset(phaseOffset);
 }
 
-sp<EventThreadConnection> EventThread::createEventConnection(ResyncCallback resyncCallback) const {
-    return new EventThreadConnection(const_cast<EventThread*>(this), std::move(resyncCallback));
+sp<EventThreadConnection> EventThread::createEventConnection(
+        ResyncCallback resyncCallback, ISurfaceComposer::ConfigChanged configChanged) const {
+    return new EventThreadConnection(const_cast<EventThread*>(this), std::move(resyncCallback),
+                                     configChanged);
 }
 
 status_t EventThread::registerDisplayEventConnection(const sp<EventThreadConnection>& connection) {
@@ -398,9 +406,11 @@
                                      const sp<EventThreadConnection>& connection) const {
     switch (event.header.type) {
         case DisplayEventReceiver::DISPLAY_EVENT_HOTPLUG:
-        case DisplayEventReceiver::DISPLAY_EVENT_CONFIG_CHANGED:
             return true;
 
+        case DisplayEventReceiver::DISPLAY_EVENT_CONFIG_CHANGED:
+            return connection->configChanged == ISurfaceComposer::eConfigChangedDispatch;
+
         case DisplayEventReceiver::DISPLAY_EVENT_VSYNC:
             switch (connection->vsyncRequest) {
                 case VSyncRequest::None:
diff --git a/services/surfaceflinger/Scheduler/EventThread.h b/services/surfaceflinger/Scheduler/EventThread.h
index 61530c6..dd23b88 100644
--- a/services/surfaceflinger/Scheduler/EventThread.h
+++ b/services/surfaceflinger/Scheduler/EventThread.h
@@ -69,7 +69,8 @@
 
 class EventThreadConnection : public BnDisplayEventConnection {
 public:
-    EventThreadConnection(EventThread*, ResyncCallback);
+    EventThreadConnection(EventThread*, ResyncCallback,
+                          ISurfaceComposer::ConfigChanged configChanged);
     virtual ~EventThreadConnection();
 
     virtual status_t postEvent(const DisplayEventReceiver::Event& event);
@@ -82,6 +83,7 @@
     const ResyncCallback resyncCallback;
 
     VSyncRequest vsyncRequest = VSyncRequest::None;
+    const ISurfaceComposer::ConfigChanged configChanged;
 
 private:
     virtual void onFirstRef();
@@ -93,7 +95,8 @@
 public:
     virtual ~EventThread();
 
-    virtual sp<EventThreadConnection> createEventConnection(ResyncCallback) const = 0;
+    virtual sp<EventThreadConnection> createEventConnection(
+            ResyncCallback, ISurfaceComposer::ConfigChanged configChanged) const = 0;
 
     // called before the screen is turned off from main thread
     virtual void onScreenReleased() = 0;
@@ -128,7 +131,8 @@
     EventThread(std::unique_ptr<VSyncSource>, InterceptVSyncsCallback, const char* threadName);
     ~EventThread();
 
-    sp<EventThreadConnection> createEventConnection(ResyncCallback) const override;
+    sp<EventThreadConnection> createEventConnection(
+            ResyncCallback, ISurfaceComposer::ConfigChanged configChanged) const override;
 
     status_t registerDisplayEventConnection(const sp<EventThreadConnection>& connection) override;
     void setVsyncRate(uint32_t rate, const sp<EventThreadConnection>& connection) override;
diff --git a/services/surfaceflinger/Scheduler/MessageQueue.cpp b/services/surfaceflinger/Scheduler/MessageQueue.cpp
index baf900d..fcb307f 100644
--- a/services/surfaceflinger/Scheduler/MessageQueue.cpp
+++ b/services/surfaceflinger/Scheduler/MessageQueue.cpp
@@ -96,7 +96,8 @@
     }
 
     mEventThread = eventThread;
-    mEvents = eventThread->createEventConnection(std::move(resyncCallback));
+    mEvents = eventThread->createEventConnection(std::move(resyncCallback),
+                                                 ISurfaceComposer::eConfigChangedSuppress);
     mEvents->stealReceiveChannel(&mEventTube);
     mLooper->addFd(mEventTube.getFd(), 0, Looper::EVENT_INPUT, MessageQueue::cb_eventReceiver,
                    this);
diff --git a/services/surfaceflinger/Scheduler/Scheduler.cpp b/services/surfaceflinger/Scheduler/Scheduler.cpp
index e2a348e..afcf3d4 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.cpp
+++ b/services/surfaceflinger/Scheduler/Scheduler.cpp
@@ -129,7 +129,8 @@
                             std::move(interceptCallback));
 
     auto eventThreadConnection =
-            createConnectionInternal(eventThread.get(), std::move(resyncCallback));
+            createConnectionInternal(eventThread.get(), std::move(resyncCallback),
+                                     ISurfaceComposer::eConfigChangedSuppress);
     mConnections.emplace(id,
                          std::make_unique<Connection>(new ConnectionHandle(id),
                                                       eventThreadConnection,
@@ -146,16 +147,18 @@
                                                std::move(interceptCallback), connectionName);
 }
 
-sp<EventThreadConnection> Scheduler::createConnectionInternal(EventThread* eventThread,
-                                                              ResyncCallback&& resyncCallback) {
-    return eventThread->createEventConnection(std::move(resyncCallback));
+sp<EventThreadConnection> Scheduler::createConnectionInternal(
+        EventThread* eventThread, ResyncCallback&& resyncCallback,
+        ISurfaceComposer::ConfigChanged configChanged) {
+    return eventThread->createEventConnection(std::move(resyncCallback), configChanged);
 }
 
 sp<IDisplayEventConnection> Scheduler::createDisplayEventConnection(
-        const sp<Scheduler::ConnectionHandle>& handle, ResyncCallback resyncCallback) {
+        const sp<Scheduler::ConnectionHandle>& handle, ResyncCallback resyncCallback,
+        ISurfaceComposer::ConfigChanged configChanged) {
     RETURN_VALUE_IF_INVALID(nullptr);
     return createConnectionInternal(mConnections[handle->id]->thread.get(),
-                                    std::move(resyncCallback));
+                                    std::move(resyncCallback), configChanged);
 }
 
 EventThread* Scheduler::getEventThread(const sp<Scheduler::ConnectionHandle>& handle) {
diff --git a/services/surfaceflinger/Scheduler/Scheduler.h b/services/surfaceflinger/Scheduler/Scheduler.h
index f6cc87b..6b5a8b7 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.h
+++ b/services/surfaceflinger/Scheduler/Scheduler.h
@@ -100,8 +100,9 @@
                                           ResyncCallback,
                                           impl::EventThread::InterceptVSyncsCallback);
 
-    sp<IDisplayEventConnection> createDisplayEventConnection(const sp<ConnectionHandle>& handle,
-                                                             ResyncCallback);
+    sp<IDisplayEventConnection> createDisplayEventConnection(
+            const sp<ConnectionHandle>& handle, ResyncCallback,
+            ISurfaceComposer::ConfigChanged configChanged);
 
     // Getter methods.
     EventThread* getEventThread(const sp<ConnectionHandle>& handle);
@@ -197,7 +198,8 @@
     enum class TouchState { INACTIVE, ACTIVE };
 
     // Creates a connection on the given EventThread and forwards the given callbacks.
-    sp<EventThreadConnection> createConnectionInternal(EventThread*, ResyncCallback&&);
+    sp<EventThreadConnection> createConnectionInternal(EventThread*, ResyncCallback&&,
+                                                       ISurfaceComposer::ConfigChanged);
 
     nsecs_t calculateAverage() const;
     void updateFrameSkipping(const int64_t skipCount);
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index e735e10..114eca3 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -1379,7 +1379,7 @@
 // ----------------------------------------------------------------------------
 
 sp<IDisplayEventConnection> SurfaceFlinger::createDisplayEventConnection(
-        ISurfaceComposer::VsyncSource vsyncSource) {
+        ISurfaceComposer::VsyncSource vsyncSource, ISurfaceComposer::ConfigChanged configChanged) {
     auto resyncCallback = mScheduler->makeResyncCallback([this] {
         Mutex::Autolock lock(mStateLock);
         return getVsyncPeriod();
@@ -1388,7 +1388,8 @@
     const auto& handle =
             vsyncSource == eVsyncSourceSurfaceFlinger ? mSfConnectionHandle : mAppConnectionHandle;
 
-    return mScheduler->createDisplayEventConnection(handle, std::move(resyncCallback));
+    return mScheduler->createDisplayEventConnection(handle, std::move(resyncCallback),
+                                                    configChanged);
 }
 
 // ----------------------------------------------------------------------------
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index ddfe88c..9577124 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -399,7 +399,9 @@
             const sp<IGraphicBufferProducer>& bufferProducer) const override;
     status_t getSupportedFrameTimestamps(std::vector<FrameEvent>* outSupported) const override;
     sp<IDisplayEventConnection> createDisplayEventConnection(
-            ISurfaceComposer::VsyncSource vsyncSource = eVsyncSourceApp) override;
+            ISurfaceComposer::VsyncSource vsyncSource = eVsyncSourceApp,
+            ISurfaceComposer::ConfigChanged configChanged =
+                    ISurfaceComposer::eConfigChangedSuppress) override;
     status_t captureScreen(const sp<IBinder>& displayToken, sp<GraphicBuffer>* outBuffer,
             bool& outCapturedSecureLayers, const ui::Dataspace reqDataspace,
             const ui::PixelFormat reqPixelFormat, Rect sourceCrop,
diff --git a/services/surfaceflinger/tests/unittests/EventThreadTest.cpp b/services/surfaceflinger/tests/unittests/EventThreadTest.cpp
index ea908a9..dbd9b84 100644
--- a/services/surfaceflinger/tests/unittests/EventThreadTest.cpp
+++ b/services/surfaceflinger/tests/unittests/EventThreadTest.cpp
@@ -55,8 +55,9 @@
     class MockEventThreadConnection : public EventThreadConnection {
     public:
         MockEventThreadConnection(android::impl::EventThread* eventThread,
-                                  ResyncCallback&& resyncCallback)
-              : EventThreadConnection(eventThread, std::move(resyncCallback)) {}
+                                  ResyncCallback&& resyncCallback,
+                                  ISurfaceComposer::ConfigChanged configChanged)
+              : EventThreadConnection(eventThread, std::move(resyncCallback), configChanged) {}
         MOCK_METHOD1(postEvent, status_t(const DisplayEventReceiver::Event& event));
     };
 
@@ -67,7 +68,8 @@
     ~EventThreadTest() override;
 
     void createThread();
-    sp<MockEventThreadConnection> createConnection(ConnectionEventRecorder& recorder);
+    sp<MockEventThreadConnection> createConnection(ConnectionEventRecorder& recorder,
+                                                   ISurfaceComposer::ConfigChanged configChanged);
 
     void expectVSyncSetEnabledCallReceived(bool expectedState);
     void expectVSyncSetPhaseOffsetCallReceived(nsecs_t expectedPhaseOffset);
@@ -110,7 +112,8 @@
             .WillRepeatedly(Invoke(mVSyncSetPhaseOffsetCallRecorder.getInvocable()));
 
     createThread();
-    mConnection = createConnection(mConnectionEventCallRecorder);
+    mConnection = createConnection(mConnectionEventCallRecorder,
+                                   ISurfaceComposer::eConfigChangedDispatch);
 
     // A display must be connected for VSYNC events to be delivered.
     mThread->onHotplugReceived(INTERNAL_DISPLAY_ID, true);
@@ -138,9 +141,10 @@
 }
 
 sp<EventThreadTest::MockEventThreadConnection> EventThreadTest::createConnection(
-        ConnectionEventRecorder& recorder) {
+        ConnectionEventRecorder& recorder, ISurfaceComposer::ConfigChanged configChanged) {
     sp<MockEventThreadConnection> connection =
-            new MockEventThreadConnection(mThread.get(), mResyncCallRecorder.getInvocable());
+            new MockEventThreadConnection(mThread.get(), mResyncCallRecorder.getInvocable(),
+                                          configChanged);
     EXPECT_CALL(*connection, postEvent(_)).WillRepeatedly(Invoke(recorder.getInvocable()));
     return connection;
 }
@@ -267,7 +271,9 @@
 TEST_F(EventThreadTest, setVsyncRateZeroPostsNoVSyncEventsToThatConnection) {
     // Create a first connection, register it, and request a vsync rate of zero.
     ConnectionEventRecorder firstConnectionEventRecorder{0};
-    sp<MockEventThreadConnection> firstConnection = createConnection(firstConnectionEventRecorder);
+    sp<MockEventThreadConnection> firstConnection =
+            createConnection(firstConnectionEventRecorder,
+                             ISurfaceComposer::eConfigChangedSuppress);
     mThread->setVsyncRate(0, firstConnection);
 
     // By itself, this should not enable vsync events
@@ -277,7 +283,8 @@
     // However if there is another connection which wants events at a nonzero rate.....
     ConnectionEventRecorder secondConnectionEventRecorder{0};
     sp<MockEventThreadConnection> secondConnection =
-            createConnection(secondConnectionEventRecorder);
+            createConnection(secondConnectionEventRecorder,
+                             ISurfaceComposer::eConfigChangedSuppress);
     mThread->setVsyncRate(1, secondConnection);
 
     // EventThread should enable vsync callbacks.
@@ -363,7 +370,9 @@
 
 TEST_F(EventThreadTest, connectionsRemovedIfEventDeliveryError) {
     ConnectionEventRecorder errorConnectionEventRecorder{NO_MEMORY};
-    sp<MockEventThreadConnection> errorConnection = createConnection(errorConnectionEventRecorder);
+    sp<MockEventThreadConnection> errorConnection =
+            createConnection(errorConnectionEventRecorder,
+                             ISurfaceComposer::eConfigChangedSuppress);
     mThread->setVsyncRate(1, errorConnection);
 
     // EventThread should enable vsync callbacks.
@@ -387,7 +396,9 @@
 
 TEST_F(EventThreadTest, eventsDroppedIfNonfatalEventDeliveryError) {
     ConnectionEventRecorder errorConnectionEventRecorder{WOULD_BLOCK};
-    sp<MockEventThreadConnection> errorConnection = createConnection(errorConnectionEventRecorder);
+    sp<MockEventThreadConnection> errorConnection =
+            createConnection(errorConnectionEventRecorder,
+                             ISurfaceComposer::eConfigChangedSuppress);
     mThread->setVsyncRate(1, errorConnection);
 
     // EventThread should enable vsync callbacks.
@@ -449,5 +460,18 @@
     expectConfigChangedEventReceivedByConnection(DISPLAY_ID_64BIT, 7);
 }
 
+TEST_F(EventThreadTest, suppressConfigChanged) {
+    ConnectionEventRecorder suppressConnectionEventRecorder{0};
+    sp<MockEventThreadConnection> suppressConnection =
+            createConnection(suppressConnectionEventRecorder,
+                             ISurfaceComposer::eConfigChangedSuppress);
+
+    mThread->onConfigChanged(INTERNAL_DISPLAY_ID, 9);
+    expectConfigChangedEventReceivedByConnection(INTERNAL_DISPLAY_ID, 9);
+
+    auto args = suppressConnectionEventRecorder.waitForCall();
+    ASSERT_FALSE(args.has_value());
+}
+
 } // namespace
 } // namespace android
diff --git a/services/surfaceflinger/tests/unittests/SchedulerTest.cpp b/services/surfaceflinger/tests/unittests/SchedulerTest.cpp
index 1f8b111..af5ccbc 100644
--- a/services/surfaceflinger/tests/unittests/SchedulerTest.cpp
+++ b/services/surfaceflinger/tests/unittests/SchedulerTest.cpp
@@ -25,7 +25,8 @@
     class MockEventThreadConnection : public android::EventThreadConnection {
     public:
         explicit MockEventThreadConnection(EventThread* eventThread)
-              : EventThreadConnection(eventThread, ResyncCallback()) {}
+              : EventThreadConnection(eventThread, ResyncCallback(),
+                                      ISurfaceComposer::eConfigChangedSuppress) {}
         ~MockEventThreadConnection() = default;
 
         MOCK_METHOD1(stealReceiveChannel, status_t(gui::BitTube* outChannel));
@@ -81,7 +82,7 @@
 
     // createConnection call to scheduler makes a createEventConnection call to EventThread. Make
     // sure that call gets executed and returns an EventThread::Connection object.
-    EXPECT_CALL(*mEventThread, createEventConnection(_))
+    EXPECT_CALL(*mEventThread, createEventConnection(_, _))
             .WillRepeatedly(Return(mEventThreadConnection));
 
     mConnectionHandle = mScheduler->createConnection("appConnection", 16, ResyncCallback(),
@@ -105,7 +106,10 @@
     // exceptions, just gracefully continues.
     sp<IDisplayEventConnection> returnedValue;
     ASSERT_NO_FATAL_FAILURE(
-            returnedValue = mScheduler->createDisplayEventConnection(nullptr, ResyncCallback()));
+            returnedValue =
+                    mScheduler->createDisplayEventConnection(nullptr, ResyncCallback(),
+                                                             ISurfaceComposer::
+                                                                     eConfigChangedSuppress));
     EXPECT_TRUE(returnedValue == nullptr);
     EXPECT_TRUE(mScheduler->getEventThread(nullptr) == nullptr);
     EXPECT_TRUE(mScheduler->getEventConnection(nullptr) == nullptr);
@@ -126,7 +130,9 @@
     sp<IDisplayEventConnection> returnedValue;
     ASSERT_NO_FATAL_FAILURE(
             returnedValue =
-                    mScheduler->createDisplayEventConnection(connectionHandle, ResyncCallback()));
+                    mScheduler->createDisplayEventConnection(connectionHandle, ResyncCallback(),
+                                                             ISurfaceComposer::
+                                                                     eConfigChangedSuppress));
     EXPECT_TRUE(returnedValue == nullptr);
     EXPECT_TRUE(mScheduler->getEventThread(connectionHandle) == nullptr);
     EXPECT_TRUE(mScheduler->getEventConnection(connectionHandle) == nullptr);
@@ -155,7 +161,9 @@
     sp<IDisplayEventConnection> returnedValue;
     ASSERT_NO_FATAL_FAILURE(
             returnedValue =
-                    mScheduler->createDisplayEventConnection(mConnectionHandle, ResyncCallback()));
+                    mScheduler->createDisplayEventConnection(mConnectionHandle, ResyncCallback(),
+                                                             ISurfaceComposer::
+                                                                     eConfigChangedSuppress));
     EXPECT_TRUE(returnedValue != nullptr);
     ASSERT_EQ(returnedValue, mEventThreadConnection);
 
diff --git a/services/surfaceflinger/tests/unittests/TestableScheduler.h b/services/surfaceflinger/tests/unittests/TestableScheduler.h
index c3d2b8d..cb6980e 100644
--- a/services/surfaceflinger/tests/unittests/TestableScheduler.h
+++ b/services/surfaceflinger/tests/unittests/TestableScheduler.h
@@ -17,6 +17,7 @@
 #pragma once
 
 #include <gmock/gmock.h>
+#include <gui/ISurfaceComposer.h>
 
 #include "Scheduler/EventThread.h"
 #include "Scheduler/RefreshRateConfigs.h"
@@ -34,7 +35,8 @@
     // Scheduler::Connection. This allows plugging in mock::EventThread.
     sp<Scheduler::ConnectionHandle> addConnection(std::unique_ptr<EventThread> eventThread) {
         sp<EventThreadConnection> eventThreadConnection =
-                new EventThreadConnection(eventThread.get(), ResyncCallback());
+                new EventThreadConnection(eventThread.get(), ResyncCallback(),
+                                          ISurfaceComposer::eConfigChangedSuppress);
         const int64_t id = sNextId++;
         mConnections.emplace(id,
                              std::make_unique<Scheduler::Connection>(new ConnectionHandle(id),
diff --git a/services/surfaceflinger/tests/unittests/mock/MockEventThread.h b/services/surfaceflinger/tests/unittests/mock/MockEventThread.h
index 5b5f8e7..ed35ebf 100644
--- a/services/surfaceflinger/tests/unittests/mock/MockEventThread.h
+++ b/services/surfaceflinger/tests/unittests/mock/MockEventThread.h
@@ -28,7 +28,8 @@
     EventThread();
     ~EventThread() override;
 
-    MOCK_CONST_METHOD1(createEventConnection, sp<EventThreadConnection>(ResyncCallback));
+    MOCK_CONST_METHOD2(createEventConnection,
+                       sp<EventThreadConnection>(ResyncCallback, ISurfaceComposer::ConfigChanged));
     MOCK_METHOD0(onScreenReleased, void());
     MOCK_METHOD0(onScreenAcquired, void());
     MOCK_METHOD2(onHotplugReceived, void(PhysicalDisplayId, bool));