diff options
author | 2019-01-25 02:35:50 -0800 | |
---|---|---|
committer | 2019-02-02 10:14:22 -0800 | |
commit | dcb38bbd32eb96ec46d69658390353a853b3af6d (patch) | |
tree | 78b3424dde3c1eac9969482afaff98462dc48221 | |
parent | 8a0222e629b82dda35840aa74eeec55bcc16999d (diff) |
SF: Plumb physical display IDs to libgui
This CL replaces ISurfaceComposer::{eDisplayIdMain,eDisplayIdHdmi} with
the stable 64-bit display IDs generated by SF. Note that the 64-bit IDs
fall back to the old values if the HWC API for display identification is
not supported.
Bug: 74619554
Test: LocalDisplayAdapter and Choreographer receive 64-bit IDs
Test: 64-bit IDs fall back to 0 and 1 on HWC 2.2 and below
Change-Id: I3c08eff6eb8bb179ecce596ab2820a2aa44c8649
27 files changed, 323 insertions, 240 deletions
diff --git a/cmds/flatland/GLHelper.cpp b/cmds/flatland/GLHelper.cpp index 62d2fa1548..d398559ee8 100644 --- a/cmds/flatland/GLHelper.cpp +++ b/cmds/flatland/GLHelper.cpp @@ -222,9 +222,9 @@ bool GLHelper::createNamedSurfaceTexture(GLuint name, uint32_t w, uint32_t h, } bool GLHelper::computeWindowScale(uint32_t w, uint32_t h, float* scale) { - sp<IBinder> dpy = mSurfaceComposerClient->getBuiltInDisplay(0); + const sp<IBinder> dpy = mSurfaceComposerClient->getInternalDisplayToken(); if (dpy == nullptr) { - fprintf(stderr, "SurfaceComposer::getBuiltInDisplay failed.\n"); + fprintf(stderr, "SurfaceComposer::getInternalDisplayToken failed.\n"); return false; } diff --git a/libs/gui/ISurfaceComposer.cpp b/libs/gui/ISurfaceComposer.cpp index bef68ef22f..4357f798df 100644 --- a/libs/gui/ISurfaceComposer.cpp +++ b/libs/gui/ISurfaceComposer.cpp @@ -275,12 +275,25 @@ public: remote()->transact(BnSurfaceComposer::DESTROY_DISPLAY, data, &reply); } - virtual sp<IBinder> getBuiltInDisplay(int32_t id) - { + virtual std::vector<PhysicalDisplayId> getPhysicalDisplayIds() const { + Parcel data, reply; + data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); + if (remote()->transact(BnSurfaceComposer::GET_PHYSICAL_DISPLAY_IDS, data, &reply) == + NO_ERROR) { + std::vector<PhysicalDisplayId> displayIds; + if (reply.readUint64Vector(&displayIds) == NO_ERROR) { + return displayIds; + } + } + + return {}; + } + + virtual sp<IBinder> getPhysicalDisplayToken(PhysicalDisplayId displayId) const { Parcel data, reply; data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor()); - data.writeInt32(id); - remote()->transact(BnSurfaceComposer::GET_BUILT_IN_DISPLAY, data, &reply); + data.writeUint64(displayId); + remote()->transact(BnSurfaceComposer::GET_PHYSICAL_DISPLAY_TOKEN, data, &reply); return reply.readStrongBinder(); } @@ -932,10 +945,10 @@ status_t BnSurfaceComposer::onTransact( destroyDisplay(display); return NO_ERROR; } - case GET_BUILT_IN_DISPLAY: { + case GET_PHYSICAL_DISPLAY_TOKEN: { CHECK_INTERFACE(ISurfaceComposer, data, reply); - int32_t id = data.readInt32(); - sp<IBinder> display(getBuiltInDisplay(id)); + PhysicalDisplayId displayId = data.readUint64(); + sp<IBinder> display = getPhysicalDisplayToken(displayId); reply->writeStrongBinder(display); return NO_ERROR; } @@ -1294,12 +1307,14 @@ status_t BnSurfaceComposer::onTransact( } return error; } + case GET_PHYSICAL_DISPLAY_IDS: { + CHECK_INTERFACE(ISurfaceComposer, data, reply); + return reply->writeUint64Vector(getPhysicalDisplayIds()); + } default: { return BBinder::onTransact(code, data, reply, flags); } } } -// ---------------------------------------------------------------------------- - -}; +} // namespace android diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp index 1f726b2ba4..3affa23482 100644 --- a/libs/gui/Surface.cpp +++ b/libs/gui/Surface.cpp @@ -321,8 +321,11 @@ status_t Surface::getFrameTimestamps(uint64_t frameNumber, status_t Surface::getWideColorSupport(bool* supported) { ATRACE_CALL(); - sp<IBinder> display( - composerService()->getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain)); + const sp<IBinder> display = composerService()->getInternalDisplayToken(); + if (display == nullptr) { + return NAME_NOT_FOUND; + } + *supported = false; status_t error = composerService()->isWideColorDisplay(display, supported); return error; @@ -331,8 +334,11 @@ status_t Surface::getWideColorSupport(bool* supported) { status_t Surface::getHdrSupport(bool* supported) { ATRACE_CALL(); - sp<IBinder> display( - composerService()->getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain)); + const sp<IBinder> display = composerService()->getInternalDisplayToken(); + if (display == nullptr) { + return NAME_NOT_FOUND; + } + HdrCapabilities hdrCapabilities; status_t err = composerService()->getHdrCapabilities(display, &hdrCapabilities); diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp index c712bde97d..90656d60c7 100644 --- a/libs/gui/SurfaceComposerClient.cpp +++ b/libs/gui/SurfaceComposerClient.cpp @@ -374,8 +374,20 @@ void SurfaceComposerClient::destroyDisplay(const sp<IBinder>& display) { return ComposerService::getComposerService()->destroyDisplay(display); } -sp<IBinder> SurfaceComposerClient::getBuiltInDisplay(int32_t id) { - return ComposerService::getComposerService()->getBuiltInDisplay(id); +std::vector<PhysicalDisplayId> SurfaceComposerClient::getPhysicalDisplayIds() { + return ComposerService::getComposerService()->getPhysicalDisplayIds(); +} + +std::optional<PhysicalDisplayId> SurfaceComposerClient::getInternalDisplayId() { + return ComposerService::getComposerService()->getInternalDisplayId(); +} + +sp<IBinder> SurfaceComposerClient::getPhysicalDisplayToken(PhysicalDisplayId displayId) { + return ComposerService::getComposerService()->getPhysicalDisplayToken(displayId); +} + +sp<IBinder> SurfaceComposerClient::getInternalDisplayToken() { + return ComposerService::getComposerService()->getInternalDisplayToken(); } void SurfaceComposerClient::Transaction::setAnimationTransaction() { diff --git a/libs/gui/include/gui/DisplayEventReceiver.h b/libs/gui/include/gui/DisplayEventReceiver.h index a4102dfe03..8c3f46305c 100644 --- a/libs/gui/include/gui/DisplayEventReceiver.h +++ b/libs/gui/include/gui/DisplayEventReceiver.h @@ -58,7 +58,7 @@ public: struct Header { uint32_t type; - uint32_t id; + PhysicalDisplayId displayId; nsecs_t timestamp __attribute__((aligned(8))); }; diff --git a/libs/gui/include/gui/ISurfaceComposer.h b/libs/gui/include/gui/ISurfaceComposer.h index 3899f6a3d0..9d6b8729d0 100644 --- a/libs/gui/include/gui/ISurfaceComposer.h +++ b/libs/gui/include/gui/ISurfaceComposer.h @@ -34,6 +34,7 @@ #include <ui/GraphicTypes.h> #include <ui/PixelFormat.h> +#include <optional> #include <vector> namespace android { @@ -71,11 +72,6 @@ public: eEarlyWakeup = 0x04 }; - enum { - eDisplayIdMain = 0, - eDisplayIdHdmi = 1 - }; - enum Rotation { eRotateNone = 0, eRotate90 = 1, @@ -88,7 +84,7 @@ public: eVsyncSourceSurfaceFlinger = 1 }; - /* + /* * Create a connection with SurfaceFlinger. */ virtual sp<ISurfaceComposerClient> createConnection() = 0; @@ -108,10 +104,26 @@ public: */ virtual void destroyDisplay(const sp<IBinder>& display) = 0; - /* get the token for the existing default displays. possible values - * for id are eDisplayIdMain and eDisplayIdHdmi. + /* get stable IDs for connected physical displays. + */ + virtual std::vector<PhysicalDisplayId> getPhysicalDisplayIds() const = 0; + + // TODO(b/74619554): Remove this stopgap once the framework is display-agnostic. + std::optional<PhysicalDisplayId> getInternalDisplayId() const { + const auto displayIds = getPhysicalDisplayIds(); + return displayIds.empty() ? std::nullopt : std::make_optional(displayIds.front()); + } + + /* get token for a physical display given its stable ID obtained via getPhysicalDisplayIds or a + * DisplayEventReceiver hotplug event. */ - virtual sp<IBinder> getBuiltInDisplay(int32_t id) = 0; + virtual sp<IBinder> getPhysicalDisplayToken(PhysicalDisplayId displayId) const = 0; + + // TODO(b/74619554): Remove this stopgap once the framework is display-agnostic. + sp<IBinder> getInternalDisplayToken() const { + const auto displayId = getInternalDisplayId(); + return displayId ? getPhysicalDisplayToken(*displayId) : nullptr; + } /* open/close transactions. requires ACCESS_SURFACE_FLINGER permission */ virtual void setTransactionState(const Vector<ComposerState>& state, @@ -346,7 +358,7 @@ public: CREATE_DISPLAY_EVENT_CONNECTION, CREATE_DISPLAY, DESTROY_DISPLAY, - GET_BUILT_IN_DISPLAY, + GET_PHYSICAL_DISPLAY_TOKEN, SET_TRANSACTION_STATE, AUTHENTICATE_SURFACE, GET_SUPPORTED_FRAME_TIMESTAMPS, @@ -377,6 +389,7 @@ public: UNCACHE_BUFFER, IS_WIDE_COLOR_DISPLAY, GET_DISPLAY_NATIVE_PRIMARIES, + GET_PHYSICAL_DISPLAY_IDS, // Always append new enum to the end. }; diff --git a/libs/gui/include/gui/SurfaceComposerClient.h b/libs/gui/include/gui/SurfaceComposerClient.h index 8e2bb2b6e6..f92c0fe547 100644 --- a/libs/gui/include/gui/SurfaceComposerClient.h +++ b/libs/gui/include/gui/SurfaceComposerClient.h @@ -202,9 +202,13 @@ public: //! Destroy a virtual display static void destroyDisplay(const sp<IBinder>& display); - //! Get the token for the existing default displays. - //! Possible values for id are eDisplayIdMain and eDisplayIdHdmi. - static sp<IBinder> getBuiltInDisplay(int32_t id); + //! Get stable IDs for connected physical displays + static std::vector<PhysicalDisplayId> getPhysicalDisplayIds(); + static std::optional<PhysicalDisplayId> getInternalDisplayId(); + + //! Get token for a physical display given its stable ID + static sp<IBinder> getPhysicalDisplayToken(PhysicalDisplayId displayId); + static sp<IBinder> getInternalDisplayToken(); static status_t enableVSyncInjections(bool enable); diff --git a/libs/gui/tests/DisplayedContentSampling_test.cpp b/libs/gui/tests/DisplayedContentSampling_test.cpp index 5443812bff..b647aaba8f 100644 --- a/libs/gui/tests/DisplayedContentSampling_test.cpp +++ b/libs/gui/tests/DisplayedContentSampling_test.cpp @@ -32,7 +32,7 @@ protected: void SetUp() { mComposerClient = new SurfaceComposerClient; ASSERT_EQ(OK, mComposerClient->initCheck()); - mDisplayToken = mComposerClient->getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain); + mDisplayToken = mComposerClient->getInternalDisplayToken(); ASSERT_TRUE(mDisplayToken); } diff --git a/libs/gui/tests/EndToEndNativeInputTest.cpp b/libs/gui/tests/EndToEndNativeInputTest.cpp index ac97733508..4a7848020f 100644 --- a/libs/gui/tests/EndToEndNativeInputTest.cpp +++ b/libs/gui/tests/EndToEndNativeInputTest.cpp @@ -233,9 +233,11 @@ public: mComposerClient = new SurfaceComposerClient; ASSERT_EQ(NO_ERROR, mComposerClient->initCheck()); + const auto display = mComposerClient->getInternalDisplayToken(); + ASSERT_FALSE(display == nullptr); + DisplayInfo info; - auto display = mComposerClient->getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain); - SurfaceComposerClient::getDisplayInfo(display, &info); + ASSERT_EQ(NO_ERROR, mComposerClient->getDisplayInfo(display, &info)); // After a new buffer is queued, SurfaceFlinger is notified and will // latch the new buffer on next vsync. Let's heuristically wait for 3 diff --git a/libs/gui/tests/Surface_test.cpp b/libs/gui/tests/Surface_test.cpp index 1705fd7383..ca58574e95 100644 --- a/libs/gui/tests/Surface_test.cpp +++ b/libs/gui/tests/Surface_test.cpp @@ -131,8 +131,10 @@ TEST_F(SurfaceTest, ScreenshotsOfProtectedBuffersSucceed) { // Verify the screenshot works with no protected buffers. sp<ISurfaceComposer> sf(ComposerService::getComposerService()); - sp<IBinder> display(sf->getBuiltInDisplay( - ISurfaceComposer::eDisplayIdMain)); + + const sp<IBinder> display = sf->getInternalDisplayToken(); + ASSERT_FALSE(display == nullptr); + sp<GraphicBuffer> outBuffer; ASSERT_EQ(NO_ERROR, sf->captureScreen(display, &outBuffer, ui::Dataspace::V0_SRGB, @@ -552,7 +554,8 @@ public: sp<IBinder> createDisplay(const String8& /*displayName*/, bool /*secure*/) override { return nullptr; } void destroyDisplay(const sp<IBinder>& /*display */) override {} - sp<IBinder> getBuiltInDisplay(int32_t /*id*/) override { return nullptr; } + std::vector<PhysicalDisplayId> getPhysicalDisplayIds() const override { return {}; } + sp<IBinder> getPhysicalDisplayToken(PhysicalDisplayId) const override { return nullptr; } void setTransactionState(const Vector<ComposerState>& /*state*/, const Vector<DisplayState>& /*displays*/, uint32_t /*flags*/, const sp<IBinder>& /*applyToken*/, diff --git a/libs/ui/include/ui/GraphicTypes.h b/libs/ui/include/ui/GraphicTypes.h index 4b03e44978..5dc56c8181 100644 --- a/libs/ui/include/ui/GraphicTypes.h +++ b/libs/ui/include/ui/GraphicTypes.h @@ -16,13 +16,21 @@ #pragma once +#include <cinttypes> +#include <cstdint> + #include <android/hardware/graphics/common/1.1/types.h> #include <android/hardware/graphics/common/1.2/types.h> #include <system/graphics.h> +#define ANDROID_PHYSICAL_DISPLAY_ID_FORMAT PRIu64 + +namespace android { + +using PhysicalDisplayId = uint64_t; + // android::ui::* in this header file will alias different types as // the HIDL interface is updated. -namespace android { namespace ui { using android::hardware::graphics::common::V1_1::RenderIntent; diff --git a/opengl/tests/lib/WindowSurface.cpp b/opengl/tests/lib/WindowSurface.cpp index b06422a98c..a0bd4e2409 100644 --- a/opengl/tests/lib/WindowSurface.cpp +++ b/opengl/tests/lib/WindowSurface.cpp @@ -34,8 +34,12 @@ WindowSurface::WindowSurface() { } // Get main display parameters. - sp<IBinder> mainDpy = SurfaceComposerClient::getBuiltInDisplay( - ISurfaceComposer::eDisplayIdMain); + const auto mainDpy = SurfaceComposerClient::getInternalDisplayToken(); + if (mainDpy == nullptr) { + fprintf(stderr, "ERROR: no display\n"); + return; + } + DisplayInfo mainDpyInfo; err = SurfaceComposerClient::getDisplayInfo(mainDpy, &mainDpyInfo); if (err != NO_ERROR) { diff --git a/services/surfaceflinger/DisplayHardware/DisplayIdentification.h b/services/surfaceflinger/DisplayHardware/DisplayIdentification.h index 1599995297..d63cd79b03 100644 --- a/services/surfaceflinger/DisplayHardware/DisplayIdentification.h +++ b/services/surfaceflinger/DisplayHardware/DisplayIdentification.h @@ -23,10 +23,12 @@ #include <string_view> #include <vector> +#include <ui/GraphicTypes.h> + namespace android { struct DisplayId { - using Type = uint64_t; + using Type = PhysicalDisplayId; Type value; uint16_t manufacturerId() const; diff --git a/services/surfaceflinger/Scheduler/EventThread.cpp b/services/surfaceflinger/Scheduler/EventThread.cpp index 52abe9ca38..91ae087adb 100644 --- a/services/surfaceflinger/Scheduler/EventThread.cpp +++ b/services/surfaceflinger/Scheduler/EventThread.cpp @@ -69,24 +69,28 @@ std::string toString(const EventThreadConnection& connection) { std::string toString(const DisplayEventReceiver::Event& event) { switch (event.header.type) { case DisplayEventReceiver::DISPLAY_EVENT_HOTPLUG: - return StringPrintf("Hotplug{displayId=%u, %s}", event.header.id, + return StringPrintf("Hotplug{displayId=%" ANDROID_PHYSICAL_DISPLAY_ID_FORMAT ", %s}", + event.header.displayId, event.hotplug.connected ? "connected" : "disconnected"); case DisplayEventReceiver::DISPLAY_EVENT_VSYNC: - return StringPrintf("VSync{displayId=%u, count=%u}", event.header.id, - event.vsync.count); + return StringPrintf("VSync{displayId=%" ANDROID_PHYSICAL_DISPLAY_ID_FORMAT + ", count=%u}", + event.header.displayId, event.vsync.count); default: return "Event{}"; } } -DisplayEventReceiver::Event makeHotplug(uint32_t displayId, nsecs_t timestamp, bool connected) { +DisplayEventReceiver::Event makeHotplug(PhysicalDisplayId displayId, nsecs_t timestamp, + bool connected) { DisplayEventReceiver::Event event; event.header = {DisplayEventReceiver::DISPLAY_EVENT_HOTPLUG, displayId, timestamp}; event.hotplug.connected = connected; return event; } -DisplayEventReceiver::Event makeVSync(uint32_t displayId, nsecs_t timestamp, uint32_t count) { +DisplayEventReceiver::Event makeVSync(PhysicalDisplayId displayId, nsecs_t timestamp, + uint32_t count) { DisplayEventReceiver::Event event; event.header = {DisplayEventReceiver::DISPLAY_EVENT_VSYNC, displayId, timestamp}; event.vsync.count = count; @@ -290,10 +294,9 @@ void EventThread::onVSyncEvent(nsecs_t timestamp) { mCondition.notify_all(); } -void EventThread::onHotplugReceived(DisplayType displayType, bool connected) { +void EventThread::onHotplugReceived(PhysicalDisplayId displayId, bool connected) { std::lock_guard<std::mutex> lock(mMutex); - const uint32_t displayId = displayType == DisplayType::Primary ? 0 : 1; mPendingEvents.push_back(makeHotplug(displayId, systemTime(), connected)); mCondition.notify_all(); } @@ -312,9 +315,9 @@ void EventThread::threadMain(std::unique_lock<std::mutex>& lock) { switch (event->header.type) { case DisplayEventReceiver::DISPLAY_EVENT_HOTPLUG: if (event->hotplug.connected && !mVSyncState) { - mVSyncState.emplace(event->header.id); + mVSyncState.emplace(event->header.displayId); } else if (!event->hotplug.connected && mVSyncState && - mVSyncState->displayId == event->header.id) { + mVSyncState->displayId == event->header.displayId) { mVSyncState.reset(); } break; @@ -440,8 +443,9 @@ void EventThread::dump(std::string& result) const { StringAppendF(&result, "%s: state=%s VSyncState=", mThreadName, toCString(mState)); if (mVSyncState) { - StringAppendF(&result, "{displayId=%u, count=%u%s}\n", mVSyncState->displayId, - mVSyncState->count, mVSyncState->synthetic ? ", synthetic" : ""); + StringAppendF(&result, "{displayId=%" ANDROID_PHYSICAL_DISPLAY_ID_FORMAT ", count=%u%s}\n", + mVSyncState->displayId, mVSyncState->count, + mVSyncState->synthetic ? ", synthetic" : ""); } else { StringAppendF(&result, "none\n"); } diff --git a/services/surfaceflinger/Scheduler/EventThread.h b/services/surfaceflinger/Scheduler/EventThread.h index 89b799e59f..62b6a8b65f 100644 --- a/services/surfaceflinger/Scheduler/EventThread.h +++ b/services/surfaceflinger/Scheduler/EventThread.h @@ -94,9 +94,6 @@ private: class EventThread { public: - // TODO: Remove once stable display IDs are plumbed through SF/WM interface. - enum class DisplayType { Primary, External }; - virtual ~EventThread(); virtual sp<EventThreadConnection> createEventConnection( @@ -108,8 +105,7 @@ public: // called after the screen is turned on from main thread virtual void onScreenAcquired() = 0; - // called when receiving a hotplug event - virtual void onHotplugReceived(DisplayType displayType, bool connected) = 0; + virtual void onHotplugReceived(PhysicalDisplayId displayId, bool connected) = 0; virtual void dump(std::string& result) const = 0; @@ -151,8 +147,7 @@ public: // called after the screen is turned on from main thread void onScreenAcquired() override; - // called when receiving a hotplug event - void onHotplugReceived(DisplayType displayType, bool connected) override; + void onHotplugReceived(PhysicalDisplayId displayId, bool connected) override; void dump(std::string& result) const override; @@ -199,9 +194,9 @@ private: // VSYNC state of connected display. struct VSyncState { - explicit VSyncState(uint32_t displayId) : displayId(displayId) {} + explicit VSyncState(PhysicalDisplayId displayId) : displayId(displayId) {} - const uint32_t displayId; + const PhysicalDisplayId displayId; // Number of VSYNC events since display was connected. uint32_t count = 0; diff --git a/services/surfaceflinger/Scheduler/Scheduler.cpp b/services/surfaceflinger/Scheduler/Scheduler.cpp index 00820f15fd..a29877e884 100644 --- a/services/surfaceflinger/Scheduler/Scheduler.cpp +++ b/services/surfaceflinger/Scheduler/Scheduler.cpp @@ -29,7 +29,6 @@ #include <android/hardware/configstore/1.2/ISurfaceFlingerConfigs.h> #include <configstore/Utils.h> #include <cutils/properties.h> -#include <gui/ISurfaceComposer.h> #include <ui/DisplayStatInfo.h> #include <utils/Timers.h> #include <utils/Trace.h> @@ -128,9 +127,9 @@ sp<EventThreadConnection> Scheduler::getEventConnection(const sp<ConnectionHandl } void Scheduler::hotplugReceived(const sp<Scheduler::ConnectionHandle>& handle, - EventThread::DisplayType displayType, bool connected) { + PhysicalDisplayId displayId, bool connected) { RETURN_IF_INVALID(); - mConnections[handle->id]->thread->onHotplugReceived(displayType, connected); + mConnections[handle->id]->thread->onHotplugReceived(displayId, connected); } void Scheduler::onScreenAcquired(const sp<Scheduler::ConnectionHandle>& handle) { diff --git a/services/surfaceflinger/Scheduler/Scheduler.h b/services/surfaceflinger/Scheduler/Scheduler.h index b7176050a7..e77dc06c34 100644 --- a/services/surfaceflinger/Scheduler/Scheduler.h +++ b/services/surfaceflinger/Scheduler/Scheduler.h @@ -19,8 +19,8 @@ #include <cstdint> #include <memory> -#include <gui/ISurfaceComposer.h> #include <ui/DisplayStatInfo.h> +#include <ui/GraphicTypes.h> #include "DispSync.h" #include "EventControlThread.h" @@ -85,7 +85,7 @@ public: sp<EventThreadConnection> getEventConnection(const sp<ConnectionHandle>& handle); // Should be called when receiving a hotplug event. - void hotplugReceived(const sp<ConnectionHandle>& handle, EventThread::DisplayType displayType, + void hotplugReceived(const sp<ConnectionHandle>& handle, PhysicalDisplayId displayId, bool connected); // Should be called after the screen is turned on. diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 2cf2cd8a5d..4c1b267397 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -496,21 +496,30 @@ void SurfaceFlinger::destroyDisplay(const sp<IBinder>& displayToken) { setTransactionFlags(eDisplayTransactionNeeded); } -sp<IBinder> SurfaceFlinger::getBuiltInDisplay(int32_t id) { - std::optional<DisplayId> displayId; +std::vector<PhysicalDisplayId> SurfaceFlinger::getPhysicalDisplayIds() const { + Mutex::Autolock lock(mStateLock); - if (id == HWC_DISPLAY_PRIMARY) { - displayId = getInternalDisplayId(); - } else if (id == HWC_DISPLAY_EXTERNAL) { - displayId = getExternalDisplayId(); + const auto internalDisplayId = getInternalDisplayIdLocked(); + if (!internalDisplayId) { + return {}; } - if (!displayId) { - ALOGE("%s: Invalid display %d", __FUNCTION__, id); - return nullptr; + std::vector<PhysicalDisplayId> displayIds; + displayIds.reserve(mPhysicalDisplayTokens.size()); + displayIds.push_back(internalDisplayId->value); + + for (const auto& [id, token] : mPhysicalDisplayTokens) { + if (id != *internalDisplayId) { + displayIds.push_back(id.value); + } } - return getPhysicalDisplayToken(*displayId); + return displayIds; +} + +sp<IBinder> SurfaceFlinger::getPhysicalDisplayToken(PhysicalDisplayId displayId) const { + Mutex::Autolock lock(mStateLock); + return getPhysicalDisplayTokenLocked(DisplayId{displayId}); } status_t SurfaceFlinger::getColorManagement(bool* outGetColorManagement) const { @@ -614,9 +623,9 @@ void SurfaceFlinger::init() { // start the EventThread if (mUseScheduler) { - mScheduler = getFactory().createScheduler([this](bool enabled) { - setVsyncEnabled(EventThread::DisplayType::Primary, enabled); - }); + mScheduler = getFactory().createScheduler( + [this](bool enabled) { setPrimaryVsyncEnabled(enabled); }); + // TODO(b/113612090): Currently we assume that if scheduler is turned on, then the refresh // rate is 90. Once b/122905403 is completed, this should be updated accordingly. mPhaseOffsets->setRefreshRateType( @@ -705,7 +714,7 @@ void SurfaceFlinger::init() { } mEventControlThread = getFactory().createEventControlThread( - [this](bool enabled) { setVsyncEnabled(EventThread::DisplayType::Primary, enabled); }); + [this](bool enabled) { setPrimaryVsyncEnabled(enabled); }); // initialize our drawing state mDrawingState = mCurrentState; @@ -820,7 +829,9 @@ status_t SurfaceFlinger::getDisplayConfigs(const sp<IBinder>& displayToken, return BAD_VALUE; } - const auto displayId = getPhysicalDisplayId(displayToken); + ConditionalLock lock(mStateLock, std::this_thread::get_id() != mMainThreadId); + + const auto displayId = getPhysicalDisplayIdLocked(displayToken); if (!displayId) { return NAME_NOT_FOUND; } @@ -844,8 +855,6 @@ status_t SurfaceFlinger::getDisplayConfigs(const sp<IBinder>& displayToken, configs->clear(); - ConditionalLock _l(mStateLock, - std::this_thread::get_id() != mMainThreadId); for (const auto& hwConfig : getHwComposer().getConfigs(*displayId)) { DisplayInfo info = DisplayInfo(); @@ -858,7 +867,7 @@ status_t SurfaceFlinger::getDisplayConfigs(const sp<IBinder>& displayToken, info.viewportW = info.w; info.viewportH = info.h; - if (displayId == getInternalDisplayId()) { + if (displayId == getInternalDisplayIdLocked()) { // The density of the device is provided by a build property float density = Density::getBuildDensity() / 160.0f; if (density == 0) { @@ -914,7 +923,7 @@ status_t SurfaceFlinger::getDisplayConfigs(const sp<IBinder>& displayToken, // All non-virtual displays are currently considered secure. info.secure = true; - if (displayId == getInternalDisplayId() && + if (displayId == getInternalDisplayIdLocked() && primaryDisplayOrientation & DisplayState::eOrientationSwapMask) { std::swap(info.w, info.h); } @@ -1012,15 +1021,15 @@ status_t SurfaceFlinger::getDisplayColorModes(const sp<IBinder>& displayToken, return BAD_VALUE; } - const auto displayId = getPhysicalDisplayId(displayToken); - if (!displayId) { - return NAME_NOT_FOUND; - } - std::vector<ColorMode> modes; { - ConditionalLock _l(mStateLock, - std::this_thread::get_id() != mMainThreadId); + ConditionalLock lock(mStateLock, std::this_thread::get_id() != mMainThreadId); + + const auto displayId = getPhysicalDisplayIdLocked(displayToken); + if (!displayId) { + return NAME_NOT_FOUND; + } + modes = getHwComposer().getColorModes(*displayId); } outColorModes->clear(); @@ -1330,7 +1339,7 @@ void SurfaceFlinger::run() { } nsecs_t SurfaceFlinger::getVsyncPeriod() const { - const auto displayId = getInternalDisplayId(); + const auto displayId = getInternalDisplayIdLocked(); if (!displayId || !getHwComposer().isConnected(*displayId)) { return 0; } @@ -1447,9 +1456,10 @@ void SurfaceFlinger::getCompositorTiming(CompositorTiming* compositorTiming) { *compositorTiming = getBE().mCompositorTiming; } -void SurfaceFlinger::setRefreshRateTo(float newFps) { - const auto displayId = getInternalDisplayId(); - if (!displayId || mBootStage != BootStage::FINISHED) { +// TODO(b/123715322): Fix thread safety. +void SurfaceFlinger::setRefreshRateTo(float newFps) NO_THREAD_SAFETY_ANALYSIS { + const auto display = getDefaultDisplayDeviceLocked(); + if (!display || mBootStage != BootStage::FINISHED) { return; } // TODO(b/113612090): There should be a message queue flush here. Because this esentially @@ -1458,8 +1468,7 @@ void SurfaceFlinger::setRefreshRateTo(float newFps) { // refresh cycle. // Don't do any updating if the current fps is the same as the new one. - const auto activeConfig = getHwComposer().getActiveConfig(*displayId); - const nsecs_t currentVsyncPeriod = activeConfig->getVsyncPeriod(); + const nsecs_t currentVsyncPeriod = getVsyncPeriod(); if (currentVsyncPeriod == 0) { return; } @@ -1470,7 +1479,7 @@ void SurfaceFlinger::setRefreshRateTo(float newFps) { return; } - auto configs = getHwComposer().getConfigs(*displayId); + auto configs = getHwComposer().getConfigs(*display->getId()); for (int i = 0; i < configs.size(); i++) { const nsecs_t vsyncPeriod = configs.at(i)->getVsyncPeriod(); if (vsyncPeriod == 0) { @@ -1480,11 +1489,12 @@ void SurfaceFlinger::setRefreshRateTo(float newFps) { // TODO(b/113612090): There should be a better way at determining which config // has the right refresh rate. if (std::abs(fps - newFps) <= 1) { - const auto display = getBuiltInDisplay(HWC_DISPLAY_PRIMARY); - if (!display) return; + const sp<IBinder> token = display->getDisplayToken().promote(); + LOG_ALWAYS_FATAL_IF(token == nullptr); + // This is posted in async function to avoid deadlock when getDisplayDevice // requires mStateLock. - setActiveConfigAsync(display, i); + setActiveConfigAsync(token, i); ATRACE_INT("FPS", newFps); } } @@ -1524,10 +1534,10 @@ void SurfaceFlinger::onRefreshReceived(int sequenceId, hwc2_display_t /*hwcDispl repaintEverythingForHWC(); } -void SurfaceFlinger::setVsyncEnabled(EventThread::DisplayType /*displayType*/, bool enabled) { +void SurfaceFlinger::setPrimaryVsyncEnabled(bool enabled) { ATRACE_CALL(); Mutex::Autolock lock(mStateLock); - if (const auto displayId = getInternalDisplayId()) { + if (const auto displayId = getInternalDisplayIdLocked()) { getHwComposer().setVsyncEnabled(*displayId, enabled ? HWC2::Vsync::Enable : HWC2::Vsync::Disable); } @@ -2593,14 +2603,13 @@ void SurfaceFlinger::processDisplayHotplugEventsLocked() { mPendingHotplugEvents.clear(); } -void SurfaceFlinger::dispatchDisplayHotplugEvent(EventThread::DisplayType displayType, - bool connected) { +void SurfaceFlinger::dispatchDisplayHotplugEvent(PhysicalDisplayId displayId, bool connected) { if (mUseScheduler) { - mScheduler->hotplugReceived(mAppConnectionHandle, displayType, connected); - mScheduler->hotplugReceived(mSfConnectionHandle, displayType, connected); + mScheduler->hotplugReceived(mAppConnectionHandle, displayId, connected); + mScheduler->hotplugReceived(mSfConnectionHandle, displayId, connected); } else { - mEventThread->onHotplugReceived(displayType, connected); - mSFEventThread->onHotplugReceived(displayType, connected); + mEventThread->onHotplugReceived(displayId, connected); + mSFEventThread->onHotplugReceived(displayId, connected); } } @@ -2616,7 +2625,7 @@ sp<DisplayDevice> SurfaceFlinger::setupNewDisplayDeviceInternal( creationArgs.hasWideColorGamut = false; creationArgs.supportedPerFrameMetadata = 0; - const bool isInternalDisplay = displayId && displayId == getInternalDisplayId(); + const bool isInternalDisplay = displayId && displayId == getInternalDisplayIdLocked(); creationArgs.isPrimary = isInternalDisplay; if (useColorManagement && displayId) { @@ -2699,19 +2708,18 @@ void SurfaceFlinger::processDisplayChangesLocked() { for (size_t i = 0; i < dc;) { const ssize_t j = curr.indexOfKey(draw.keyAt(i)); if (j < 0) { - // Save display IDs before disconnecting. - const auto internalDisplayId = getInternalDisplayId(); - const auto externalDisplayId = getExternalDisplayId(); - // in drawing state but not in current state if (const auto display = getDisplayDeviceLocked(draw.keyAt(i))) { + // Save display ID before disconnecting. + const auto displayId = display->getId(); display->disconnect(); + + if (!display->isVirtual()) { + LOG_ALWAYS_FATAL_IF(!displayId); + dispatchDisplayHotplugEvent(displayId->value, false); + } } - if (internalDisplayId && internalDisplayId == draw[i].displayId) { - dispatchDisplayHotplugEvent(EventThread::DisplayType::Primary, false); - } else if (externalDisplayId && externalDisplayId == draw[i].displayId) { - dispatchDisplayHotplugEvent(EventThread::DisplayType::External, false); - } + mDisplays.erase(draw.keyAt(i)); } else { // this display is in both lists. see if something changed. @@ -2814,12 +2822,7 @@ void SurfaceFlinger::processDisplayChangesLocked() { dispSurface, producer)); if (!state.isVirtual()) { LOG_ALWAYS_FATAL_IF(!displayId); - - if (displayId == getInternalDisplayId()) { - dispatchDisplayHotplugEvent(EventThread::DisplayType::Primary, true); - } else if (displayId == getExternalDisplayId()) { - dispatchDisplayHotplugEvent(EventThread::DisplayType::External, true); - } + dispatchDisplayHotplugEvent(displayId->value, true); } } } @@ -4829,7 +4832,7 @@ void SurfaceFlinger::dumpAllLocked(const DumpArgs& args, std::string& result) co " gpu_to_cpu_unsupported : %d\n", mTransactionFlags.load(), !mGpuToCpuSupported); - if (const auto displayId = getInternalDisplayId(); + if (const auto displayId = getInternalDisplayIdLocked(); displayId && getHwComposer().isConnected(*displayId)) { const auto activeConfig = getHwComposer().getActiveConfig(*displayId); StringAppendF(&result, @@ -4999,7 +5002,8 @@ status_t SurfaceFlinger::CheckTransactCodeCredentials(uint32_t code) { // information, so it is OK to pass them. case AUTHENTICATE_SURFACE: case GET_ACTIVE_CONFIG: - case GET_BUILT_IN_DISPLAY: + case GET_PHYSICAL_DISPLAY_IDS: + case GET_PHYSICAL_DISPLAY_TOKEN: case GET_DISPLAY_COLOR_MODES: case GET_DISPLAY_NATIVE_PRIMARIES: case GET_DISPLAY_CONFIGS: diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index a48e8113d3..73b0cde413 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -313,7 +313,7 @@ public: compositionengine::CompositionEngine& getCompositionEngine() const; // returns the default Display - sp<const DisplayDevice> getDefaultDisplayDevice() const { + sp<const DisplayDevice> getDefaultDisplayDevice() { Mutex::Autolock _l(mStateLock); return getDefaultDisplayDeviceLocked(); } @@ -327,7 +327,7 @@ public: // enable/disable h/w composer event // TODO: this should be made accessible only to EventThread - void setVsyncEnabled(EventThread::DisplayType displayType, bool enabled); + void setPrimaryVsyncEnabled(bool enabled); // called on the main thread by MessageQueue when an internal message // is received @@ -414,7 +414,8 @@ private: sp<ISurfaceComposerClient> createConnection() override; sp<IBinder> createDisplay(const String8& displayName, bool secure) override; void destroyDisplay(const sp<IBinder>& displayToken) override; - sp<IBinder> getBuiltInDisplay(int32_t id) override; + std::vector<PhysicalDisplayId> getPhysicalDisplayIds() const override; + sp<IBinder> getPhysicalDisplayToken(PhysicalDisplayId displayId) const override; void setTransactionState(const Vector<ComposerState>& state, const Vector<DisplayState>& displays, uint32_t flags, const sp<IBinder>& applyToken, @@ -657,7 +658,7 @@ private: } sp<DisplayDevice> getDefaultDisplayDeviceLocked() { - if (const auto token = getInternalDisplayToken()) { + if (const auto token = getInternalDisplayTokenLocked()) { return getDisplayDeviceLocked(token); } return nullptr; @@ -761,7 +762,7 @@ private: void processDisplayChangesLocked(); void processDisplayHotplugEventsLocked(); - void dispatchDisplayHotplugEvent(EventThread::DisplayType displayType, bool connected); + void dispatchDisplayHotplugEvent(PhysicalDisplayId displayId, bool connected); /* ------------------------------------------------------------------------ * VSync @@ -801,12 +802,12 @@ private: /* * Display identification */ - sp<IBinder> getPhysicalDisplayToken(DisplayId displayId) const { + sp<IBinder> getPhysicalDisplayTokenLocked(DisplayId displayId) const { const auto it = mPhysicalDisplayTokens.find(displayId); return it != mPhysicalDisplayTokens.end() ? it->second : nullptr; } - std::optional<DisplayId> getPhysicalDisplayId(const sp<IBinder>& displayToken) const { + std::optional<DisplayId> getPhysicalDisplayIdLocked(const sp<IBinder>& displayToken) const { for (const auto& [id, token] : mPhysicalDisplayTokens) { if (token == displayToken) { return id; @@ -816,22 +817,16 @@ private: } // TODO(b/74619554): Remove special cases for primary display. - sp<IBinder> getInternalDisplayToken() const { - const auto displayId = getInternalDisplayId(); - return displayId ? getPhysicalDisplayToken(*displayId) : nullptr; + sp<IBinder> getInternalDisplayTokenLocked() const { + const auto displayId = getInternalDisplayIdLocked(); + return displayId ? getPhysicalDisplayTokenLocked(*displayId) : nullptr; } - std::optional<DisplayId> getInternalDisplayId() const { + std::optional<DisplayId> getInternalDisplayIdLocked() const { const auto hwcDisplayId = getHwComposer().getInternalHwcDisplayId(); return hwcDisplayId ? getHwComposer().toPhysicalDisplayId(*hwcDisplayId) : std::nullopt; } - // TODO(b/74619554): Remove special cases for external display. - std::optional<DisplayId> getExternalDisplayId() const { - const auto hwcDisplayId = getHwComposer().getExternalHwcDisplayId(); - return hwcDisplayId ? getHwComposer().toPhysicalDisplayId(*hwcDisplayId) : std::nullopt; - } - /* * Debugging & dumpsys */ @@ -951,7 +946,6 @@ private: std::unique_ptr<VSyncSource> mSfEventThreadSource; std::unique_ptr<InjectVSyncSource> mVSyncInjector; std::unique_ptr<EventControlThread> mEventControlThread; - std::unordered_map<DisplayId, sp<IBinder>> mPhysicalDisplayTokens; // Calculates correct offsets. VSyncModulator mVsyncModulator; @@ -985,6 +979,7 @@ private: // this may only be written from the main thread with mStateLock held // it may be read from other threads with mStateLock held std::map<wp<IBinder>, sp<DisplayDevice>> mDisplays; + std::unordered_map<DisplayId, sp<IBinder>> mPhysicalDisplayTokens; // don't use a lock for these, we don't care int mDebugRegion; diff --git a/services/surfaceflinger/tests/Credentials_test.cpp b/services/surfaceflinger/tests/Credentials_test.cpp index f021d3dfa7..61d09daed2 100644 --- a/services/surfaceflinger/tests/Credentials_test.cpp +++ b/services/surfaceflinger/tests/Credentials_test.cpp @@ -62,9 +62,11 @@ protected: } void setupBackgroundSurface() { - mDisplay = SurfaceComposerClient::getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain); + mDisplay = SurfaceComposerClient::getInternalDisplayToken(); + ASSERT_FALSE(mDisplay == nullptr); + DisplayInfo info; - SurfaceComposerClient::getDisplayInfo(mDisplay, &info); + ASSERT_EQ(NO_ERROR, SurfaceComposerClient::getDisplayInfo(mDisplay, &info)); const ssize_t displayWidth = info.w; const ssize_t displayHeight = info.h; @@ -170,10 +172,8 @@ TEST_F(CredentialsTest, ClientInitTest) { } TEST_F(CredentialsTest, GetBuiltInDisplayAccessTest) { - std::function<bool()> condition = [=]() { - sp<IBinder> display( - SurfaceComposerClient::getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain)); - return (display != nullptr); + std::function<bool()> condition = [] { + return SurfaceComposerClient::getInternalDisplayToken() != nullptr; }; // Anyone can access display information. ASSERT_NO_FATAL_FAILURE(checkWithPrivileges(condition, true, true)); @@ -183,7 +183,7 @@ TEST_F(CredentialsTest, AllowedGetterMethodsTest) { // The following methods are tested with a UID that is not root, graphics, // or system, to show that anyone can access them. setBinUID(); - sp<IBinder> display(SurfaceComposerClient::getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain)); + const auto display = SurfaceComposerClient::getInternalDisplayToken(); ASSERT_TRUE(display != nullptr); DisplayInfo info; @@ -199,7 +199,7 @@ TEST_F(CredentialsTest, AllowedGetterMethodsTest) { } TEST_F(CredentialsTest, GetDisplayColorModesTest) { - sp<IBinder> display(SurfaceComposerClient::getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain)); + const auto display = SurfaceComposerClient::getInternalDisplayToken(); std::function<status_t()> condition = [=]() { Vector<ui::ColorMode> outColorModes; return SurfaceComposerClient::getDisplayColorModes(display, &outColorModes); @@ -208,7 +208,7 @@ TEST_F(CredentialsTest, GetDisplayColorModesTest) { } TEST_F(CredentialsTest, GetDisplayNativePrimariesTest) { - sp<IBinder> display(SurfaceComposerClient::getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain)); + const auto display = SurfaceComposerClient::getInternalDisplayToken(); std::function<status_t()> condition = [=]() { ui::DisplayPrimaries primaries; return SurfaceComposerClient::getDisplayNativePrimaries(display, primaries); @@ -217,7 +217,7 @@ TEST_F(CredentialsTest, GetDisplayNativePrimariesTest) { } TEST_F(CredentialsTest, SetActiveConfigTest) { - sp<IBinder> display(SurfaceComposerClient::getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain)); + const auto display = SurfaceComposerClient::getInternalDisplayToken(); std::function<status_t()> condition = [=]() { return SurfaceComposerClient::setActiveConfig(display, 0); }; @@ -225,7 +225,7 @@ TEST_F(CredentialsTest, SetActiveConfigTest) { } TEST_F(CredentialsTest, SetActiveColorModeTest) { - sp<IBinder> display(SurfaceComposerClient::getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain)); + const auto display = SurfaceComposerClient::getInternalDisplayToken(); std::function<status_t()> condition = [=]() { return SurfaceComposerClient::setActiveColorMode(display, ui::ColorMode::NATIVE); }; @@ -258,7 +258,7 @@ TEST_F(CredentialsTest, DISABLED_DestroyDisplayTest) { } TEST_F(CredentialsTest, CaptureTest) { - sp<IBinder> display(SurfaceComposerClient::getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain)); + const auto display = SurfaceComposerClient::getInternalDisplayToken(); std::function<status_t()> condition = [=]() { sp<GraphicBuffer> outBuffer; return ScreenshotClient::capture(display, ui::Dataspace::V0_SRGB, @@ -324,7 +324,8 @@ TEST_F(CredentialsTest, GetLayerDebugInfo) { } TEST_F(CredentialsTest, IsWideColorDisplayBasicCorrectness) { - sp<IBinder> display(SurfaceComposerClient::getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain)); + const auto display = SurfaceComposerClient::getInternalDisplayToken(); + ASSERT_FALSE(display == nullptr); bool result = false; status_t error = SurfaceComposerClient::isWideColorDisplay(display, &result); ASSERT_EQ(NO_ERROR, error); @@ -346,7 +347,8 @@ TEST_F(CredentialsTest, IsWideColorDisplayBasicCorrectness) { } TEST_F(CredentialsTest, IsWideColorDisplayWithPrivileges) { - sp<IBinder> display(SurfaceComposerClient::getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain)); + const auto display = SurfaceComposerClient::getInternalDisplayToken(); + ASSERT_FALSE(display == nullptr); std::function<status_t()> condition = [=]() { bool result = false; return SurfaceComposerClient::isWideColorDisplay(display, &result); diff --git a/services/surfaceflinger/tests/SurfaceInterceptor_test.cpp b/services/surfaceflinger/tests/SurfaceInterceptor_test.cpp index 8ec3e154e3..5cc946aa79 100644 --- a/services/surfaceflinger/tests/SurfaceInterceptor_test.cpp +++ b/services/surfaceflinger/tests/SurfaceInterceptor_test.cpp @@ -240,10 +240,12 @@ void SurfaceInterceptorTest::capture(TestAction action, Trace* outTrace) { } void SurfaceInterceptorTest::setupBackgroundSurface() { - sp<IBinder> display(SurfaceComposerClient::getBuiltInDisplay( - ISurfaceComposer::eDisplayIdMain)); + const auto display = SurfaceComposerClient::getInternalDisplayToken(); + ASSERT_FALSE(display == nullptr); + DisplayInfo info; - SurfaceComposerClient::getDisplayInfo(display, &info); + ASSERT_EQ(NO_ERROR, SurfaceComposerClient::getDisplayInfo(display, &info)); + ssize_t displayWidth = info.w; ssize_t displayHeight = info.h; diff --git a/services/surfaceflinger/tests/Transaction_test.cpp b/services/surfaceflinger/tests/Transaction_test.cpp index 56d3bd49a8..05a73dcd94 100644 --- a/services/surfaceflinger/tests/Transaction_test.cpp +++ b/services/surfaceflinger/tests/Transaction_test.cpp @@ -195,13 +195,12 @@ static void fillSurfaceRGBA8(const sp<SurfaceControl>& sc, uint8_t r, uint8_t g, class ScreenCapture : public RefBase { public: static void captureScreen(std::unique_ptr<ScreenCapture>* sc) { - sp<ISurfaceComposer> sf(ComposerService::getComposerService()); - sp<IBinder> display(sf->getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain)); + const auto sf = ComposerService::getComposerService(); + const auto token = sf->getInternalDisplayToken(); SurfaceComposerClient::Transaction().apply(true); sp<GraphicBuffer> outBuffer; - ASSERT_EQ(NO_ERROR, - sf->captureScreen(display, &outBuffer, Rect(), 0, 0, false)); + ASSERT_EQ(NO_ERROR, sf->captureScreen(token, &outBuffer, Rect(), 0, 0, false)); *sc = std::make_unique<ScreenCapture>(outBuffer); } @@ -324,7 +323,6 @@ protected: ASSERT_NO_FATAL_FAILURE(SetUpDisplay()); sp<ISurfaceComposer> sf(ComposerService::getComposerService()); - sp<IBinder> binder = sf->getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain); ASSERT_NO_FATAL_FAILURE(sf->getColorManagement(&mColorManagementUsed)); } @@ -502,12 +500,12 @@ protected: private: void SetUpDisplay() { - mDisplay = mClient->getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain); - ASSERT_NE(nullptr, mDisplay.get()) << "failed to get built-in display"; + mDisplay = mClient->getInternalDisplayToken(); + ASSERT_FALSE(mDisplay == nullptr) << "failed to get display"; // get display width/height DisplayInfo info; - SurfaceComposerClient::getDisplayInfo(mDisplay, &info); + ASSERT_EQ(NO_ERROR, SurfaceComposerClient::getDisplayInfo(mDisplay, &info)); mDisplayWidth = info.w; mDisplayHeight = info.h; mDisplayRect = @@ -558,8 +556,7 @@ public: return mDelegate->screenshot(); case RenderPath::VIRTUAL_DISPLAY: - sp<IBinder> mainDisplay = - SurfaceComposerClient::getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain); + const auto mainDisplay = SurfaceComposerClient::getInternalDisplayToken(); DisplayInfo mainDisplayInfo; SurfaceComposerClient::getDisplayInfo(mainDisplay, &mainDisplayInfo); @@ -3930,10 +3927,11 @@ protected: LayerTransactionTest::SetUp(); ASSERT_EQ(NO_ERROR, mClient->initCheck()); - sp<IBinder> display( - SurfaceComposerClient::getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain)); + const auto display = SurfaceComposerClient::getInternalDisplayToken(); + ASSERT_FALSE(display == nullptr); + DisplayInfo info; - SurfaceComposerClient::getDisplayInfo(display, &info); + ASSERT_EQ(NO_ERROR, SurfaceComposerClient::getDisplayInfo(display, &info)); ssize_t displayWidth = info.w; ssize_t displayHeight = info.h; diff --git a/services/surfaceflinger/tests/fakehwc/SFFakeHwc_test.cpp b/services/surfaceflinger/tests/fakehwc/SFFakeHwc_test.cpp index 16e08918a0..f9e0b6413b 100644 --- a/services/surfaceflinger/tests/fakehwc/SFFakeHwc_test.cpp +++ b/services/surfaceflinger/tests/fakehwc/SFFakeHwc_test.cpp @@ -145,7 +145,7 @@ protected: void TearDown() override; void waitForDisplayTransaction(); - bool waitForHotplugEvent(uint32_t id, bool connected); + bool waitForHotplugEvent(PhysicalDisplayId displayId, bool connected); sp<IComposer> mFakeService; sp<SurfaceComposerClient> mComposerClient; @@ -242,7 +242,7 @@ void DisplayTest::waitForDisplayTransaction() { mMockComposer->runVSyncAndWait(); } -bool DisplayTest::waitForHotplugEvent(uint32_t id, bool connected) { +bool DisplayTest::waitForHotplugEvent(PhysicalDisplayId displayId, bool connected) { int waitCount = 20; while (waitCount--) { while (!mReceivedDisplayEvents.empty()) { @@ -250,11 +250,12 @@ bool DisplayTest::waitForHotplugEvent(uint32_t id, bool connected) { mReceivedDisplayEvents.pop_front(); ALOGV_IF(event.header.type == DisplayEventReceiver::DISPLAY_EVENT_HOTPLUG, - "event hotplug: id %d, connected %d\t", event.header.id, - event.hotplug.connected); + "event hotplug: displayId %" ANDROID_PHYSICAL_DISPLAY_ID_FORMAT + ", connected %d\t", + event.header.displayId, event.hotplug.connected); if (event.header.type == DisplayEventReceiver::DISPLAY_EVENT_HOTPLUG && - event.header.id == id && event.hotplug.connected == connected) { + event.header.displayId == displayId && event.hotplug.connected == connected) { return true; } } @@ -294,13 +295,14 @@ TEST_F(DisplayTest, Hotplug) { waitForDisplayTransaction(); - EXPECT_TRUE(waitForHotplugEvent(ISurfaceComposer::eDisplayIdHdmi, true)); + EXPECT_TRUE(waitForHotplugEvent(EXTERNAL_DISPLAY, true)); { - sp<android::IBinder> display( - SurfaceComposerClient::getBuiltInDisplay(ISurfaceComposer::eDisplayIdHdmi)); + const auto display = SurfaceComposerClient::getPhysicalDisplayToken(EXTERNAL_DISPLAY); + ASSERT_FALSE(display == nullptr); + DisplayInfo info; - SurfaceComposerClient::getDisplayInfo(display, &info); + ASSERT_EQ(NO_ERROR, SurfaceComposerClient::getDisplayInfo(display, &info)); ASSERT_EQ(400u, info.w); ASSERT_EQ(200u, info.h); @@ -328,14 +330,15 @@ TEST_F(DisplayTest, Hotplug) { waitForDisplayTransaction(); - EXPECT_TRUE(waitForHotplugEvent(ISurfaceComposer::eDisplayIdHdmi, false)); - EXPECT_TRUE(waitForHotplugEvent(ISurfaceComposer::eDisplayIdHdmi, true)); + EXPECT_TRUE(waitForHotplugEvent(EXTERNAL_DISPLAY, false)); + EXPECT_TRUE(waitForHotplugEvent(EXTERNAL_DISPLAY, true)); { - sp<android::IBinder> display( - SurfaceComposerClient::getBuiltInDisplay(ISurfaceComposer::eDisplayIdHdmi)); + const auto display = SurfaceComposerClient::getPhysicalDisplayToken(EXTERNAL_DISPLAY); + ASSERT_FALSE(display == nullptr); + DisplayInfo info; - SurfaceComposerClient::getDisplayInfo(display, &info); + ASSERT_EQ(NO_ERROR, SurfaceComposerClient::getDisplayInfo(display, &info)); ASSERT_EQ(400u, info.w); ASSERT_EQ(200u, info.h); @@ -364,11 +367,12 @@ TEST_F(DisplayTest, HotplugPrimaryDisplay) { waitForDisplayTransaction(); - EXPECT_TRUE(waitForHotplugEvent(ISurfaceComposer::eDisplayIdMain, false)); + EXPECT_TRUE(waitForHotplugEvent(PRIMARY_DISPLAY, false)); { - sp<android::IBinder> display( - SurfaceComposerClient::getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain)); + const auto display = SurfaceComposerClient::getPhysicalDisplayToken(PRIMARY_DISPLAY); + EXPECT_FALSE(display == nullptr); + DisplayInfo info; auto result = SurfaceComposerClient::getDisplayInfo(display, &info); EXPECT_NE(NO_ERROR, result); @@ -402,11 +406,12 @@ TEST_F(DisplayTest, HotplugPrimaryDisplay) { waitForDisplayTransaction(); - EXPECT_TRUE(waitForHotplugEvent(ISurfaceComposer::eDisplayIdMain, true)); + EXPECT_TRUE(waitForHotplugEvent(PRIMARY_DISPLAY, true)); { - sp<android::IBinder> display( - SurfaceComposerClient::getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain)); + const auto display = SurfaceComposerClient::getPhysicalDisplayToken(PRIMARY_DISPLAY); + EXPECT_FALSE(display == nullptr); + DisplayInfo info; auto result = SurfaceComposerClient::getDisplayInfo(display, &info); EXPECT_EQ(NO_ERROR, result); @@ -473,10 +478,11 @@ void TransactionTest::SetUp() { ASSERT_EQ(NO_ERROR, mComposerClient->initCheck()); ALOGI("TransactionTest::SetUp - display"); - sp<android::IBinder> display( - SurfaceComposerClient::getBuiltInDisplay(ISurfaceComposer::eDisplayIdMain)); + const auto display = SurfaceComposerClient::getPhysicalDisplayToken(PRIMARY_DISPLAY); + ASSERT_FALSE(display == nullptr); + DisplayInfo info; - SurfaceComposerClient::getDisplayInfo(display, &info); + ASSERT_EQ(NO_ERROR, SurfaceComposerClient::getDisplayInfo(display, &info)); mDisplayWidth = info.w; mDisplayHeight = info.h; diff --git a/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp b/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp index 4cb79ab495..da3472e3fa 100644 --- a/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp +++ b/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp @@ -45,9 +45,9 @@ namespace android { namespace { using testing::_; -using testing::ByMove; using testing::DoAll; using testing::Mock; +using testing::ResultOf; using testing::Return; using testing::SetArgPointee; @@ -321,11 +321,6 @@ struct DisplayVariant { // Whether the display is primary static constexpr Primary PRIMARY = primary; - static constexpr auto displayType() { - return static_cast<bool>(PRIMARY) ? EventThread::DisplayType::Primary - : EventThread::DisplayType::External; - } - static auto makeFakeExistingDisplayInjector(DisplayTransactionTest* test) { auto injector = FakeDisplayDeviceInjector(test->mFlinger, DISPLAY_ID::get(), @@ -1470,6 +1465,9 @@ public: template <typename Case> void setupCommonPreconditions(); + template <typename Case, bool connected> + static void expectHotplugReceived(mock::EventThread*); + template <typename Case> void setupCommonCallExpectationsForConnectProcessing(); @@ -1507,6 +1505,17 @@ void HandleTransactionLockedTest::setupCommonPreconditions() { injectFakeNativeWindowSurfaceFactory(); } +template <typename Case, bool connected> +void HandleTransactionLockedTest::expectHotplugReceived(mock::EventThread* eventThread) { + const auto convert = [](auto physicalDisplayId) { + return std::make_optional(DisplayId{physicalDisplayId}); + }; + + EXPECT_CALL(*eventThread, + onHotplugReceived(ResultOf(convert, Case::Display::DISPLAY_ID::get()), connected)) + .Times(1); +} + template <typename Case> void HandleTransactionLockedTest::setupCommonCallExpectationsForConnectProcessing() { Case::Display::setupHwcHotplugCallExpectations(this); @@ -1522,16 +1531,16 @@ void HandleTransactionLockedTest::setupCommonCallExpectationsForConnectProcessin EXPECT_CALL(*mSurfaceInterceptor, saveDisplayCreation(_)).Times(1); - EXPECT_CALL(*mEventThread, onHotplugReceived(Case::Display::displayType(), true)).Times(1); - EXPECT_CALL(*mSFEventThread, onHotplugReceived(Case::Display::displayType(), true)).Times(1); + expectHotplugReceived<Case, true>(mEventThread); + expectHotplugReceived<Case, true>(mSFEventThread); } template <typename Case> void HandleTransactionLockedTest::setupCommonCallExpectationsForDisconnectProcessing() { EXPECT_CALL(*mSurfaceInterceptor, saveDisplayDeletion(_)).Times(1); - EXPECT_CALL(*mEventThread, onHotplugReceived(Case::Display::displayType(), false)).Times(1); - EXPECT_CALL(*mSFEventThread, onHotplugReceived(Case::Display::displayType(), false)).Times(1); + expectHotplugReceived<Case, false>(mEventThread); + expectHotplugReceived<Case, false>(mSFEventThread); } template <typename Case> diff --git a/services/surfaceflinger/tests/unittests/EventThreadTest.cpp b/services/surfaceflinger/tests/unittests/EventThreadTest.cpp index dd90063d93..ad7dcb4217 100644 --- a/services/surfaceflinger/tests/unittests/EventThreadTest.cpp +++ b/services/surfaceflinger/tests/unittests/EventThreadTest.cpp @@ -36,6 +36,9 @@ using testing::Invoke; namespace android { namespace { +constexpr PhysicalDisplayId INTERNAL_DISPLAY_ID = 111; +constexpr PhysicalDisplayId EXTERNAL_DISPLAY_ID = 222; + class MockVSyncSource : public VSyncSource { public: MOCK_METHOD1(setVSyncEnabled, void(bool)); @@ -72,7 +75,7 @@ protected: ConnectionEventRecorder& connectionEventRecorder, nsecs_t expectedTimestamp, unsigned expectedCount); void expectVsyncEventReceivedByConnection(nsecs_t expectedTimestamp, unsigned expectedCount); - void expectHotplugEventReceivedByConnection(EventThread::DisplayType expectedDisplayType, + void expectHotplugEventReceivedByConnection(PhysicalDisplayId expectedDisplayId, bool expectedConnected); AsyncCallRecorder<void (*)(bool)> mVSyncSetEnabledCallRecorder; @@ -106,8 +109,8 @@ EventThreadTest::EventThreadTest() { mConnection = createConnection(mConnectionEventCallRecorder); // A display must be connected for VSYNC events to be delivered. - mThread->onHotplugReceived(EventThread::DisplayType::Primary, true); - expectHotplugEventReceivedByConnection(EventThread::DisplayType::Primary, true); + mThread->onHotplugReceived(INTERNAL_DISPLAY_ID, true); + expectHotplugEventReceivedByConnection(INTERNAL_DISPLAY_ID, true); } EventThreadTest::~EventThreadTest() { @@ -183,16 +186,13 @@ void EventThreadTest::expectVsyncEventReceivedByConnection(nsecs_t expectedTimes expectedCount); } -void EventThreadTest::expectHotplugEventReceivedByConnection( - EventThread::DisplayType expectedDisplayType, bool expectedConnected) { - const uint32_t expectedDisplayId = - expectedDisplayType == EventThread::DisplayType::Primary ? 0 : 1; - +void EventThreadTest::expectHotplugEventReceivedByConnection(PhysicalDisplayId expectedDisplayId, + bool expectedConnected) { auto args = mConnectionEventCallRecorder.waitForCall(); ASSERT_TRUE(args.has_value()); const auto& event = std::get<0>(args.value()); EXPECT_EQ(DisplayEventReceiver::DISPLAY_EVENT_HOTPLUG, event.header.type); - EXPECT_EQ(expectedDisplayId, event.header.id); + EXPECT_EQ(expectedDisplayId, event.header.displayId); EXPECT_EQ(expectedConnected, event.hotplug.connected); } @@ -212,8 +212,8 @@ TEST_F(EventThreadTest, canCreateAndDestroyThreadWithNoEventsSent) { } TEST_F(EventThreadTest, vsyncRequestIsIgnoredIfDisplayIsDisconnected) { - mThread->onHotplugReceived(EventThread::DisplayType::Primary, false); - expectHotplugEventReceivedByConnection(EventThread::DisplayType::Primary, false); + mThread->onHotplugReceived(INTERNAL_DISPLAY_ID, false); + expectHotplugEventReceivedByConnection(INTERNAL_DISPLAY_ID, false); // Signal that we want the next vsync event to be posted to the connection. mThread->requestNextVsync(mConnection, false); @@ -400,24 +400,24 @@ TEST_F(EventThreadTest, setPhaseOffsetForwardsToVSyncSource) { expectVSyncSetPhaseOffsetCallReceived(321); } -TEST_F(EventThreadTest, postHotplugPrimaryDisconnect) { - mThread->onHotplugReceived(EventThread::DisplayType::Primary, false); - expectHotplugEventReceivedByConnection(EventThread::DisplayType::Primary, false); +TEST_F(EventThreadTest, postHotplugInternalDisconnect) { + mThread->onHotplugReceived(INTERNAL_DISPLAY_ID, false); + expectHotplugEventReceivedByConnection(INTERNAL_DISPLAY_ID, false); } -TEST_F(EventThreadTest, postHotplugPrimaryConnect) { - mThread->onHotplugReceived(EventThread::DisplayType::Primary, true); - expectHotplugEventReceivedByConnection(EventThread::DisplayType::Primary, true); +TEST_F(EventThreadTest, postHotplugInternalConnect) { + mThread->onHotplugReceived(INTERNAL_DISPLAY_ID, true); + expectHotplugEventReceivedByConnection(INTERNAL_DISPLAY_ID, true); } TEST_F(EventThreadTest, postHotplugExternalDisconnect) { - mThread->onHotplugReceived(EventThread::DisplayType::External, false); - expectHotplugEventReceivedByConnection(EventThread::DisplayType::External, false); + mThread->onHotplugReceived(EXTERNAL_DISPLAY_ID, false); + expectHotplugEventReceivedByConnection(EXTERNAL_DISPLAY_ID, false); } TEST_F(EventThreadTest, postHotplugExternalConnect) { - mThread->onHotplugReceived(EventThread::DisplayType::External, true); - expectHotplugEventReceivedByConnection(EventThread::DisplayType::External, true); + mThread->onHotplugReceived(EXTERNAL_DISPLAY_ID, true); + expectHotplugEventReceivedByConnection(EXTERNAL_DISPLAY_ID, true); } } // namespace diff --git a/services/surfaceflinger/tests/unittests/SchedulerTest.cpp b/services/surfaceflinger/tests/unittests/SchedulerTest.cpp index 4d9aec6b66..0db96d95ce 100644 --- a/services/surfaceflinger/tests/unittests/SchedulerTest.cpp +++ b/services/surfaceflinger/tests/unittests/SchedulerTest.cpp @@ -18,6 +18,8 @@ using testing::Return; namespace android { +constexpr PhysicalDisplayId PHYSICAL_DISPLAY_ID = 999; + class SchedulerTest : public testing::Test { protected: class MockEventThreadConnection : public android::EventThreadConnection { @@ -104,8 +106,7 @@ TEST_F(SchedulerTest, testNullPtr) { EXPECT_TRUE(returnedValue == nullptr); EXPECT_TRUE(mScheduler->getEventThread(nullptr) == nullptr); EXPECT_TRUE(mScheduler->getEventConnection(nullptr) == nullptr); - ASSERT_NO_FATAL_FAILURE( - mScheduler->hotplugReceived(nullptr, EventThread::DisplayType::Primary, false)); + ASSERT_NO_FATAL_FAILURE(mScheduler->hotplugReceived(nullptr, PHYSICAL_DISPLAY_ID, false)); ASSERT_NO_FATAL_FAILURE(mScheduler->onScreenAcquired(nullptr)); ASSERT_NO_FATAL_FAILURE(mScheduler->onScreenReleased(nullptr)); std::string testString; @@ -129,8 +130,8 @@ TEST_F(SchedulerTest, invalidConnectionHandle) { // The EXPECT_CALLS make sure we don't call the functions on the subsequent event threads. EXPECT_CALL(*mEventThread, onHotplugReceived(_, _)).Times(0); - ASSERT_NO_FATAL_FAILURE(mScheduler->hotplugReceived(connectionHandle, - EventThread::DisplayType::Primary, false)); + ASSERT_NO_FATAL_FAILURE( + mScheduler->hotplugReceived(connectionHandle, PHYSICAL_DISPLAY_ID, false)); EXPECT_CALL(*mEventThread, onScreenAcquired()).Times(0); ASSERT_NO_FATAL_FAILURE(mScheduler->onScreenAcquired(connectionHandle)); @@ -158,10 +159,9 @@ TEST_F(SchedulerTest, validConnectionHandle) { EXPECT_TRUE(mScheduler->getEventThread(mConnectionHandle) != nullptr); EXPECT_TRUE(mScheduler->getEventConnection(mConnectionHandle) != nullptr); - EXPECT_CALL(*mEventThread, onHotplugReceived(EventThread::DisplayType::Primary, false)) - .Times(1); - ASSERT_NO_FATAL_FAILURE(mScheduler->hotplugReceived(mConnectionHandle, - EventThread::DisplayType::Primary, false)); + EXPECT_CALL(*mEventThread, onHotplugReceived(PHYSICAL_DISPLAY_ID, false)).Times(1); + ASSERT_NO_FATAL_FAILURE( + mScheduler->hotplugReceived(mConnectionHandle, PHYSICAL_DISPLAY_ID, false)); EXPECT_CALL(*mEventThread, onScreenAcquired()).Times(1); ASSERT_NO_FATAL_FAILURE(mScheduler->onScreenAcquired(mConnectionHandle)); diff --git a/services/surfaceflinger/tests/unittests/mock/MockEventThread.h b/services/surfaceflinger/tests/unittests/mock/MockEventThread.h index 3242ef12a4..aaf67e9559 100644 --- a/services/surfaceflinger/tests/unittests/mock/MockEventThread.h +++ b/services/surfaceflinger/tests/unittests/mock/MockEventThread.h @@ -31,7 +31,7 @@ public: MOCK_CONST_METHOD1(createEventConnection, sp<EventThreadConnection>(ResyncCallback)); MOCK_METHOD0(onScreenReleased, void()); MOCK_METHOD0(onScreenAcquired, void()); - MOCK_METHOD2(onHotplugReceived, void(DisplayType, bool)); + MOCK_METHOD2(onHotplugReceived, void(PhysicalDisplayId, bool)); MOCK_CONST_METHOD1(dump, void(std::string&)); MOCK_METHOD1(setPhaseOffset, void(nsecs_t phaseOffset)); MOCK_METHOD1(registerDisplayEventConnection, |