Merge "Added new arguments for screenshot request" into sc-dev
diff --git a/cmds/dumpstate/tests/dumpstate_smoke_test.cpp b/cmds/dumpstate/tests/dumpstate_smoke_test.cpp
index 0e366cb..c62d302 100644
--- a/cmds/dumpstate/tests/dumpstate_smoke_test.cpp
+++ b/cmds/dumpstate/tests/dumpstate_smoke_test.cpp
@@ -310,8 +310,12 @@
     // FS/proc/*/mountinfo size > 0
     FileExists("FS/proc/1/mountinfo", 0U, 100000U);
 
-    // FS/data/misc/profiles/cur/0/*/primary.prof size > 0
-    FileExists("FS/data/misc/profiles/cur/0/com.android.phone/primary.prof", 0U, 100000U);
+    // FS/data/misc/profiles/cur/0/*/primary.prof should exist. Also, since dumpstate only adds
+    // profiles to the zip in the non-user build, a build checking is necessary here.
+    if (!PropertiesHelper::IsUserBuild()) {
+        ZipEntry entry;
+        GetEntry(handle, "FS/data/misc/profiles/cur/0/com.android.phone/primary.prof", &entry);
+    }
 }
 
 /**
diff --git a/cmds/servicemanager/ServiceManager.cpp b/cmds/servicemanager/ServiceManager.cpp
index b21010d..0dbab4e 100644
--- a/cmds/servicemanager/ServiceManager.cpp
+++ b/cmds/servicemanager/ServiceManager.cpp
@@ -623,4 +623,21 @@
     return Status::ok();
 }
 
+Status ServiceManager::getServiceDebugInfo(std::vector<ServiceDebugInfo>* outReturn) {
+    if (!mAccess->canList(mAccess->getCallingContext())) {
+        return Status::fromExceptionCode(Status::EX_SECURITY);
+    }
+
+    outReturn->reserve(mNameToService.size());
+    for (auto const& [name, service] : mNameToService) {
+        ServiceDebugInfo info;
+        info.name = name;
+        info.debugPid = service.debugPid;
+
+        outReturn->push_back(std::move(info));
+    }
+
+    return Status::ok();
+}
+
 }  // namespace android
diff --git a/cmds/servicemanager/ServiceManager.h b/cmds/servicemanager/ServiceManager.h
index 9f43eb4..c089115 100644
--- a/cmds/servicemanager/ServiceManager.h
+++ b/cmds/servicemanager/ServiceManager.h
@@ -26,6 +26,7 @@
 
 using os::IClientCallback;
 using os::IServiceCallback;
+using os::ServiceDebugInfo;
 
 class ServiceManager : public os::BnServiceManager, public IBinder::DeathRecipient {
 public:
@@ -48,6 +49,7 @@
     binder::Status registerClientCallback(const std::string& name, const sp<IBinder>& service,
                                           const sp<IClientCallback>& cb) override;
     binder::Status tryUnregisterService(const std::string& name, const sp<IBinder>& binder) override;
+    binder::Status getServiceDebugInfo(std::vector<ServiceDebugInfo>* outReturn) override;
     void binderDied(const wp<IBinder>& who) override;
     void handleClientCallbacks();
 
diff --git a/data/etc/go_handheld_core_hardware.xml b/data/etc/go_handheld_core_hardware.xml
index 3aa2797..e6db4ad 100644
--- a/data/etc/go_handheld_core_hardware.xml
+++ b/data/etc/go_handheld_core_hardware.xml
@@ -1,4 +1,4 @@
-u<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
 <!-- Copyright (C) 2018 The Android Open Source Project
 
      Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/libs/binder/Android.bp b/libs/binder/Android.bp
index 9ea9732..2c0cca1 100644
--- a/libs/binder/Android.bp
+++ b/libs/binder/Android.bp
@@ -212,6 +212,7 @@
         "aidl/android/os/IClientCallback.aidl",
         "aidl/android/os/IServiceCallback.aidl",
         "aidl/android/os/IServiceManager.aidl",
+        "aidl/android/os/ServiceDebugInfo.aidl",
     ],
     path: "aidl",
 }
diff --git a/libs/binder/aidl/android/os/IServiceManager.aidl b/libs/binder/aidl/android/os/IServiceManager.aidl
index 2b1e492..ce30050 100644
--- a/libs/binder/aidl/android/os/IServiceManager.aidl
+++ b/libs/binder/aidl/android/os/IServiceManager.aidl
@@ -18,6 +18,7 @@
 
 import android.os.IClientCallback;
 import android.os.IServiceCallback;
+import android.os.ServiceDebugInfo;
 
 /**
  * Basic interface for finding and publishing system services.
@@ -116,4 +117,9 @@
      * Attempt to unregister and remove a service. Will fail if the service is still in use.
      */
     void tryUnregisterService(@utf8InCpp String name, IBinder service);
+
+    /**
+     * Get debug information for all currently registered services.
+     */
+    ServiceDebugInfo[] getServiceDebugInfo();
 }
diff --git a/libs/binder/aidl/android/os/ServiceDebugInfo.aidl b/libs/binder/aidl/android/os/ServiceDebugInfo.aidl
new file mode 100644
index 0000000..b95d222
--- /dev/null
+++ b/libs/binder/aidl/android/os/ServiceDebugInfo.aidl
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2021 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.os;
+
+/**
+ * Debug information associated with a registered service
+ * @hide
+ */
+parcelable ServiceDebugInfo {
+    /**
+     * Service name (see IServiceManager.addService/checkService/getService)
+     */
+    @utf8InCpp String name;
+    /**
+     * PID of service at the time of registration (may no longer be valid).
+     */
+    int debugPid;
+}
diff --git a/services/surfaceflinger/DisplayDevice.h b/services/surfaceflinger/DisplayDevice.h
index 85f2f3b..6f07964 100644
--- a/services/surfaceflinger/DisplayDevice.h
+++ b/services/surfaceflinger/DisplayDevice.h
@@ -219,6 +219,9 @@
         DisplayConnectionType type;
         hardware::graphics::composer::hal::HWDisplayId hwcDisplayId;
         std::optional<DeviceProductInfo> deviceProductInfo;
+        DisplayModes supportedModes;
+        DisplayModePtr activeMode;
+
         bool operator==(const Physical& other) const {
             return id == other.id && type == other.type && hwcDisplayId == other.hwcDisplayId;
         }
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index f89b199..1ddc909 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -155,7 +155,6 @@
 using ui::ColorMode;
 using ui::Dataspace;
 using ui::DisplayPrimaries;
-using ui::Hdr;
 using ui::RenderIntent;
 
 namespace hal = android::hardware::graphics::composer::hal;
@@ -1130,7 +1129,7 @@
 
     clearDesiredActiveConfigState();
 
-    const auto& refreshRate = getDefaultDisplayDeviceLocked()->getMode(modeId)->getFps();
+    const auto refreshRate = getDefaultDisplayDeviceLocked()->getMode(modeId)->getFps();
     mScheduler->resyncToHardwareVsync(true, refreshRate.getPeriodNsecs());
     updatePhaseConfiguration(refreshRate);
 }
@@ -1771,8 +1770,15 @@
     // calculate the expected present time once and use the cached
     // value throughout this frame to make sure all layers are
     // seeing this same value.
-    const nsecs_t lastExpectedPresentTime = mExpectedPresentTime.load();
-    mExpectedPresentTime = expectedVSyncTime;
+    if (expectedVSyncTime >= frameStart) {
+        mExpectedPresentTime = expectedVSyncTime;
+    } else {
+        const DisplayStatInfo stats = mScheduler->getDisplayStatInfo(frameStart);
+        mExpectedPresentTime = calculateExpectedPresentTime(stats);
+    }
+
+    const nsecs_t lastScheduledPresentTime = mScheduledPresentTime;
+    mScheduledPresentTime = expectedVSyncTime;
 
     // When Backpressure propagation is enabled we want to give a small grace period
     // for the present fence to fire instead of just giving up on this frame to handle cases
@@ -1798,7 +1804,7 @@
     const TracedOrdinal<bool> frameMissed = {"PrevFrameMissed",
                                              framePending ||
                                                      (previousPresentTime >= 0 &&
-                                                      (lastExpectedPresentTime <
+                                                      (lastScheduledPresentTime <
                                                        previousPresentTime - frameMissedSlop))};
     const TracedOrdinal<bool> hwcFrameMissed = {"PrevHwcFrameMissed",
                                                 mHadDeviceComposition && frameMissed};
@@ -2368,18 +2374,20 @@
         const auto it = mPhysicalDisplayTokens.find(displayId);
 
         if (event.connection == hal::Connection::CONNECTED) {
+            auto supportedModes = getHwComposer().getModes(displayId);
+            const auto activeMode = getHwComposer().getActiveMode(displayId);
+            // TODO(b/175678215) Handle the case when activeMode is not in supportedModes
+
             if (it == mPhysicalDisplayTokens.end()) {
                 ALOGV("Creating display %s", to_string(displayId).c_str());
 
-                if (event.hwcDisplayId == getHwComposer().getInternalHwcDisplayId()) {
-                    initScheduler(displayId);
-                }
-
                 DisplayDeviceState state;
                 state.physical = {.id = displayId,
                                   .type = getHwComposer().getDisplayConnectionType(displayId),
                                   .hwcDisplayId = event.hwcDisplayId,
-                                  .deviceProductInfo = std::move(info->deviceProductInfo)};
+                                  .deviceProductInfo = std::move(info->deviceProductInfo),
+                                  .supportedModes = std::move(supportedModes),
+                                  .activeMode = activeMode};
                 state.isSecure = true; // All physical displays are currently considered secure.
                 state.displayName = std::move(info->name);
 
@@ -2387,6 +2395,10 @@
                 mCurrentState.displays.add(token, state);
                 mPhysicalDisplayTokens.emplace(displayId, std::move(token));
 
+                if (event.hwcDisplayId == getHwComposer().getInternalHwcDisplayId()) {
+                    initScheduler(state);
+                }
+
                 mInterceptor->saveDisplayCreation(state);
             } else {
                 ALOGV("Recreating display %s", to_string(displayId).c_str());
@@ -2394,6 +2406,8 @@
                 const auto token = it->second;
                 auto& state = mCurrentState.displays.editValueFor(token);
                 state.sequenceId = DisplayDeviceState{}.sequenceId; // Generate new sequenceId
+                state.physical->supportedModes = std::move(supportedModes);
+                state.physical->activeMode = activeMode;
                 if (getHwComposer().updatesDeviceProductInfoOnHotplugReconnect()) {
                     state.physical->deviceProductInfo = std::move(info->deviceProductInfo);
                 }
@@ -2439,11 +2453,11 @@
 
     if (const auto& physical = state.physical) {
         creationArgs.connectionType = physical->type;
+        creationArgs.supportedModes = physical->supportedModes;
     }
 
     if (const auto id = PhysicalDisplayId::tryCast(compositionDisplay->getId())) {
         creationArgs.isPrimary = id == getInternalDisplayIdLocked();
-        creationArgs.supportedModes = getHwComposer().getModes(*id);
 
         if (useColorManagement) {
             std::vector<ColorMode> modes = getHwComposer().getColorModes(*id);
@@ -2498,9 +2512,7 @@
                                                     RenderIntent::COLORIMETRIC,
                                                     Dataspace::UNKNOWN});
     if (!state.isVirtual()) {
-        const auto physicalId = display->getPhysicalId();
-        auto activeConfigId = getHwComposer().getActiveMode(physicalId)->getId();
-        display->setActiveMode(activeConfigId);
+        display->setActiveMode(state.physical->activeMode->getId());
         display->setDeviceProductInfo(state.physical->deviceProductInfo);
     }
 
@@ -2518,10 +2530,8 @@
     int height = 0;
     ui::PixelFormat pixelFormat = static_cast<ui::PixelFormat>(PIXEL_FORMAT_UNKNOWN);
     if (state.physical) {
-        const auto& activeConfig =
-                getCompositionEngine().getHwComposer().getActiveMode(state.physical->id);
-        width = activeConfig->getWidth();
-        height = activeConfig->getHeight();
+        width = state.physical->activeMode->getWidth();
+        height = state.physical->activeMode->getHeight();
         pixelFormat = static_cast<ui::PixelFormat>(PIXEL_FORMAT_RGBA_8888);
     } else if (state.surface != nullptr) {
         int status = state.surface->query(NATIVE_WINDOW_WIDTH, &width);
@@ -2645,11 +2655,9 @@
 
             // TODO(b/175678251) Call a listener instead.
             if (currentState.physical->hwcDisplayId == getHwComposer().getInternalHwcDisplayId()) {
-                const auto displayId = currentState.physical->id;
-                const auto configs = getHwComposer().getModes(displayId);
-                const auto currentConfig = getHwComposer().getActiveMode(displayId)->getId();
-                // TODO(b/175678215) Handle the case when currentConfig is not in configs
-                mRefreshRateConfigs->updateDisplayConfigs(configs, currentConfig);
+                mRefreshRateConfigs
+                        ->updateDisplayConfigs(currentState.physical->supportedModes,
+                                               currentState.physical->activeMode->getId());
                 mVsyncConfiguration->reset();
                 updatePhaseConfiguration(mRefreshRateConfigs->getCurrentRefreshRate().getFps());
                 if (mRefreshRateOverlay) {
@@ -2932,31 +2940,29 @@
     mScheduler->onFrameRateOverridesChanged(mAppConnectionHandle, displayId);
 }
 
-void SurfaceFlinger::initScheduler(PhysicalDisplayId primaryDisplayId) {
+void SurfaceFlinger::initScheduler(const DisplayDeviceState& displayState) {
     if (mScheduler) {
         // In practice it's not allowed to hotplug in/out the primary display once it's been
         // connected during startup, but some tests do it, so just warn and return.
         ALOGW("Can't re-init scheduler");
         return;
     }
-
-    auto currentConfig = getHwComposer().getActiveMode(primaryDisplayId)->getId();
-    const auto modes = getHwComposer().getModes(primaryDisplayId);
+    const auto displayId = displayState.physical->id;
     mRefreshRateConfigs = std::make_unique<
-            scheduler::RefreshRateConfigs>(modes, currentConfig,
+            scheduler::RefreshRateConfigs>(displayState.physical->supportedModes,
+                                           displayState.physical->activeMode->getId(),
                                            android::sysprop::enable_frame_rate_override(true));
-    const auto& currRefreshRate = mRefreshRateConfigs->getRefreshRateFromConfigId(currentConfig);
-    mRefreshRateStats =
-            std::make_unique<scheduler::RefreshRateStats>(*mTimeStats, currRefreshRate.getFps(),
-                                                          hal::PowerMode::OFF);
+    const auto currRefreshRate = displayState.physical->activeMode->getFps();
+    mRefreshRateStats = std::make_unique<scheduler::RefreshRateStats>(*mTimeStats, currRefreshRate,
+                                                                      hal::PowerMode::OFF);
 
-    mVsyncConfiguration = getFactory().createVsyncConfiguration(currRefreshRate.getFps());
+    mVsyncConfiguration = getFactory().createVsyncConfiguration(currRefreshRate);
     mVsyncModulator.emplace(mVsyncConfiguration->getCurrentConfigs());
 
     // start the EventThread
     mScheduler = getFactory().createScheduler(*mRefreshRateConfigs, *this);
     const auto configs = mVsyncConfiguration->getCurrentConfigs();
-    const nsecs_t vsyncPeriod = currRefreshRate.getVsyncPeriod();
+    const nsecs_t vsyncPeriod = currRefreshRate.getPeriodNsecs();
     mAppConnectionHandle =
             mScheduler->createConnection("app", mFrameTimeline->getTokenManager(),
                                          /*workDuration=*/configs.late.appWorkDuration,
@@ -2983,7 +2989,8 @@
     // This is a bit hacky, but this avoids a back-pointer into the main SF
     // classes from EventThread, and there should be no run-time binder cost
     // anyway since there are no connected apps at this point.
-    mScheduler->onPrimaryDisplayConfigChanged(mAppConnectionHandle, primaryDisplayId, currentConfig,
+    mScheduler->onPrimaryDisplayConfigChanged(mAppConnectionHandle, displayId,
+                                              displayState.physical->activeMode->getId(),
                                               vsyncPeriod);
     static auto ignorePresentFences =
             base::GetBoolProperty("debug.sf.vsync_reactor_ignore_present_fences"s, false);
@@ -3727,9 +3734,11 @@
     if (what & layer_state_t::eRelativeLayerChanged) {
         // NOTE: index needs to be calculated before we update the state
         const auto& p = layer->getParent();
+        const auto& relativeHandle = s.relativeLayerSurfaceControl ?
+                s.relativeLayerSurfaceControl->getHandle() : nullptr;
         if (p == nullptr) {
             ssize_t idx = mCurrentState.layersSortedByZ.indexOf(layer);
-            if (layer->setRelativeLayer(s.relativeLayerSurfaceControl->getHandle(), s.z) &&
+            if (layer->setRelativeLayer(relativeHandle, s.z) &&
                 idx >= 0) {
                 mCurrentState.layersSortedByZ.removeAt(idx);
                 mCurrentState.layersSortedByZ.add(layer);
@@ -3738,7 +3747,7 @@
                 flags |= eTransactionNeeded|eTraversalNeeded;
             }
         } else {
-            if (p->setChildRelativeLayer(layer, s.relativeLayerSurfaceControl->getHandle(), s.z)) {
+            if (p->setChildRelativeLayer(layer, relativeHandle, s.z)) {
                 flags |= eTransactionNeeded|eTraversalNeeded;
             }
         }
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index dc92f98..6d146f2 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -714,7 +714,7 @@
     void commitInputWindowCommands() REQUIRES(mStateLock);
     void updateCursorAsync();
 
-    void initScheduler(PhysicalDisplayId primaryDisplayId) REQUIRES(mStateLock);
+    void initScheduler(const DisplayDeviceState&) REQUIRES(mStateLock);
     void updatePhaseConfiguration(const Fps&) REQUIRES(mStateLock);
     void setVsyncConfig(const VsyncModulator::VsyncConfig&, nsecs_t vsyncPeriod);
 
@@ -1230,6 +1230,7 @@
     std::unique_ptr<scheduler::RefreshRateStats> mRefreshRateStats;
 
     std::atomic<nsecs_t> mExpectedPresentTime = 0;
+    nsecs_t mScheduledPresentTime = 0;
     hal::Vsync mHWCVsyncPendingState = hal::Vsync::DISABLE;
 
     std::mutex mActiveConfigLock;
diff --git a/services/surfaceflinger/tests/unittests/DisplayTransactionTestHelpers.h b/services/surfaceflinger/tests/unittests/DisplayTransactionTestHelpers.h
index 9ec2d16..1664301 100644
--- a/services/surfaceflinger/tests/unittests/DisplayTransactionTestHelpers.h
+++ b/services/surfaceflinger/tests/unittests/DisplayTransactionTestHelpers.h
@@ -136,7 +136,7 @@
     DisplayTransactionTest();
 };
 
-constexpr int32_t DEFAULT_REFRESH_RATE = 16'666'667;
+constexpr int32_t DEFAULT_VSYNC_PERIOD = 16'666'667;
 constexpr int32_t DEFAULT_DPI = 320;
 constexpr int DEFAULT_VIRTUAL_DISPLAY_SURFACE_FORMAT = HAL_PIXEL_FORMAT_RGB_565;
 
@@ -436,7 +436,7 @@
                         getDisplayAttribute(HWC_DISPLAY_ID, HWC_ACTIVE_CONFIG_ID,
                                             IComposerClient::Attribute::VSYNC_PERIOD, _))
                     .WillRepeatedly(
-                            DoAll(SetArgPointee<3>(DEFAULT_REFRESH_RATE), Return(Error::NONE)));
+                            DoAll(SetArgPointee<3>(DEFAULT_VSYNC_PERIOD), Return(Error::NONE)));
             EXPECT_CALL(*test->mComposer,
                         getDisplayAttribute(HWC_DISPLAY_ID, HWC_ACTIVE_CONFIG_ID,
                                             IComposerClient::Attribute::DPI_X, _))
diff --git a/services/surfaceflinger/tests/unittests/SurfaceFlinger_OnInitializeDisplaysTest.cpp b/services/surfaceflinger/tests/unittests/SurfaceFlinger_OnInitializeDisplaysTest.cpp
index 7a9403b..ef8b149 100644
--- a/services/surfaceflinger/tests/unittests/SurfaceFlinger_OnInitializeDisplaysTest.cpp
+++ b/services/surfaceflinger/tests/unittests/SurfaceFlinger_OnInitializeDisplaysTest.cpp
@@ -86,16 +86,16 @@
     // The display refresh period should be set in the orientedDisplaySpaceRect tracker.
     FrameStats stats;
     mFlinger.getAnimFrameTracker().getStats(&stats);
-    EXPECT_EQ(DEFAULT_REFRESH_RATE, stats.refreshPeriodNano);
+    EXPECT_EQ(DEFAULT_VSYNC_PERIOD, stats.refreshPeriodNano);
 
     // The display transaction needed flag should be set.
     EXPECT_TRUE(hasTransactionFlagSet(eDisplayTransactionNeeded));
 
     // The compositor timing should be set to default values
     const auto& compositorTiming = mFlinger.getCompositorTiming();
-    EXPECT_EQ(-DEFAULT_REFRESH_RATE, compositorTiming.deadline);
-    EXPECT_EQ(DEFAULT_REFRESH_RATE, compositorTiming.interval);
-    EXPECT_EQ(DEFAULT_REFRESH_RATE, compositorTiming.presentLatency);
+    EXPECT_EQ(-DEFAULT_VSYNC_PERIOD, compositorTiming.deadline);
+    EXPECT_EQ(DEFAULT_VSYNC_PERIOD, compositorTiming.interval);
+    EXPECT_EQ(DEFAULT_VSYNC_PERIOD, compositorTiming.presentLatency);
 }
 
 } // namespace
diff --git a/services/surfaceflinger/tests/unittests/SurfaceFlinger_SetPowerModeInternalTest.cpp b/services/surfaceflinger/tests/unittests/SurfaceFlinger_SetPowerModeInternalTest.cpp
index 2117628..6502420 100644
--- a/services/surfaceflinger/tests/unittests/SurfaceFlinger_SetPowerModeInternalTest.cpp
+++ b/services/surfaceflinger/tests/unittests/SurfaceFlinger_SetPowerModeInternalTest.cpp
@@ -105,7 +105,7 @@
 
 struct DispSyncIsSupportedVariant {
     static void setupResetModelCallExpectations(DisplayTransactionTest* test) {
-        EXPECT_CALL(*test->mVsyncController, startPeriodTransition(DEFAULT_REFRESH_RATE)).Times(1);
+        EXPECT_CALL(*test->mVsyncController, startPeriodTransition(DEFAULT_VSYNC_PERIOD)).Times(1);
         EXPECT_CALL(*test->mVSyncTracker, resetModel()).Times(1);
     }
 };
diff --git a/services/surfaceflinger/tests/unittests/SurfaceFlinger_SetupNewDisplayDeviceInternalTest.cpp b/services/surfaceflinger/tests/unittests/SurfaceFlinger_SetupNewDisplayDeviceInternalTest.cpp
index 9a95ab4..2b5cb77 100644
--- a/services/surfaceflinger/tests/unittests/SurfaceFlinger_SetupNewDisplayDeviceInternalTest.cpp
+++ b/services/surfaceflinger/tests/unittests/SurfaceFlinger_SetupNewDisplayDeviceInternalTest.cpp
@@ -17,6 +17,8 @@
 #undef LOG_TAG
 #define LOG_TAG "LibSurfaceFlingerUnittests"
 
+#include "DisplayHardware/DisplayMode.h"
+
 #include "DisplayTransactionTestHelpers.h"
 
 namespace android {
@@ -232,13 +234,26 @@
     // Invocation
 
     DisplayDeviceState state;
-    if (const auto connectionType = Case::Display::CONNECTION_TYPE::value) {
+    if constexpr (constexpr auto connectionType = Case::Display::CONNECTION_TYPE::value) {
         const auto displayId = PhysicalDisplayId::tryCast(Case::Display::DISPLAY_ID::get());
         ASSERT_TRUE(displayId);
         const auto hwcDisplayId = Case::Display::HWC_DISPLAY_ID_OPT::value;
         ASSERT_TRUE(hwcDisplayId);
         mFlinger.getHwComposer().allocatePhysicalDisplay(*hwcDisplayId, *displayId);
-        state.physical = {.id = *displayId, .type = *connectionType, .hwcDisplayId = *hwcDisplayId};
+        DisplayModePtr activeMode = DisplayMode::Builder(Case::Display::HWC_ACTIVE_CONFIG_ID)
+                                            .setWidth(Case::Display::WIDTH)
+                                            .setHeight(Case::Display::HEIGHT)
+                                            .setVsyncPeriod(DEFAULT_VSYNC_PERIOD)
+                                            .setDpiX(DEFAULT_DPI)
+                                            .setDpiY(DEFAULT_DPI)
+                                            .setConfigGroup(0)
+                                            .build();
+        DisplayModes modes{activeMode};
+        state.physical = {.id = *displayId,
+                          .type = *connectionType,
+                          .hwcDisplayId = *hwcDisplayId,
+                          .supportedModes = modes,
+                          .activeMode = activeMode};
     }
 
     state.isSecure = static_cast<bool>(Case::Display::SECURE);