Loading libs/ui/Gralloc4.cpp +5 −5 Original line number Diff line number Diff line Loading @@ -1193,10 +1193,6 @@ std::string Gralloc4Mapper::dumpBuffers(bool less) const { Gralloc4Allocator::Gralloc4Allocator(const Gralloc4Mapper& mapper) : mMapper(mapper) { mAllocator = IAllocator::getService(); if (mAllocator == nullptr) { ALOGW("allocator 4.x is not supported"); return; } if (__builtin_available(android 31, *)) { if (hasIAllocatorAidl()) { mAidlAllocator = AidlIAllocator::fromBinder(ndk::SpAIBinder( Loading @@ -1204,10 +1200,14 @@ Gralloc4Allocator::Gralloc4Allocator(const Gralloc4Mapper& mapper) : mMapper(map ALOGE_IF(!mAidlAllocator, "AIDL IAllocator declared but failed to get service"); } } if (mAllocator == nullptr && mAidlAllocator == nullptr) { ALOGW("allocator 4.x is not supported"); return; } } bool Gralloc4Allocator::isLoaded() const { return mAllocator != nullptr; return mAllocator != nullptr || mAidlAllocator != nullptr; } std::string Gralloc4Allocator::dumpDebugInfo(bool less) const { Loading services/inputflinger/reader/mapper/KeyboardInputMapper.cpp +2 −0 Original line number Diff line number Diff line Loading @@ -428,6 +428,8 @@ void KeyboardInputMapper::initializeLedState(LedState& ledState, int32_t led) { } void KeyboardInputMapper::updateLedState(bool reset) { // Clear the local led state then union the global led state. mMetaState &= ~(AMETA_CAPS_LOCK_ON | AMETA_NUM_LOCK_ON | AMETA_SCROLL_LOCK_ON); mMetaState |= getContext()->getLedMetaState(); constexpr int32_t META_NUM = 3; Loading services/inputflinger/tests/InputReader_test.cpp +72 −0 Original line number Diff line number Diff line Loading @@ -4007,6 +4007,78 @@ TEST_F(KeyboardInputMapperTest, Process_toggleCapsLockState) { ASSERT_EQ(AMETA_CAPS_LOCK_ON, mapper.getMetaState()); } TEST_F(KeyboardInputMapperTest, Process_LockedKeysShouldToggleInMultiDevices) { // keyboard 1. mFakeEventHub->addLed(EVENTHUB_ID, LED_CAPSL, true /*initially on*/); mFakeEventHub->addLed(EVENTHUB_ID, LED_NUML, false /*initially off*/); mFakeEventHub->addLed(EVENTHUB_ID, LED_SCROLLL, false /*initially off*/); mFakeEventHub->addKey(EVENTHUB_ID, KEY_CAPSLOCK, 0, AKEYCODE_CAPS_LOCK, 0); mFakeEventHub->addKey(EVENTHUB_ID, KEY_NUMLOCK, 0, AKEYCODE_NUM_LOCK, 0); mFakeEventHub->addKey(EVENTHUB_ID, KEY_SCROLLLOCK, 0, AKEYCODE_SCROLL_LOCK, 0); KeyboardInputMapper& mapper1 = addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD, AINPUT_KEYBOARD_TYPE_ALPHABETIC); // keyboard 2. const std::string USB2 = "USB2"; const std::string DEVICE_NAME2 = "KEYBOARD2"; constexpr int32_t SECOND_DEVICE_ID = DEVICE_ID + 1; constexpr int32_t SECOND_EVENTHUB_ID = EVENTHUB_ID + 1; std::shared_ptr<InputDevice> device2 = newDevice(SECOND_DEVICE_ID, DEVICE_NAME2, USB2, SECOND_EVENTHUB_ID, ftl::Flags<InputDeviceClass>(0)); mFakeEventHub->addLed(SECOND_EVENTHUB_ID, LED_CAPSL, true /*initially on*/); mFakeEventHub->addLed(SECOND_EVENTHUB_ID, LED_NUML, false /*initially off*/); mFakeEventHub->addLed(SECOND_EVENTHUB_ID, LED_SCROLLL, false /*initially off*/); mFakeEventHub->addKey(SECOND_EVENTHUB_ID, KEY_CAPSLOCK, 0, AKEYCODE_CAPS_LOCK, 0); mFakeEventHub->addKey(SECOND_EVENTHUB_ID, KEY_NUMLOCK, 0, AKEYCODE_NUM_LOCK, 0); mFakeEventHub->addKey(SECOND_EVENTHUB_ID, KEY_SCROLLLOCK, 0, AKEYCODE_SCROLL_LOCK, 0); KeyboardInputMapper& mapper2 = device2->addMapper<KeyboardInputMapper>(SECOND_EVENTHUB_ID, AINPUT_SOURCE_KEYBOARD, AINPUT_KEYBOARD_TYPE_ALPHABETIC); device2->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(), 0 /*changes*/); device2->reset(ARBITRARY_TIME); // Initial metastate is AMETA_NUM_LOCK_ON, turn it off. ASSERT_TRUE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_NUML)); ASSERT_EQ(AMETA_NUM_LOCK_ON, mapper1.getMetaState()); ASSERT_EQ(AMETA_NUM_LOCK_ON, mapper2.getMetaState()); process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_NUMLOCK, 1); process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_NUMLOCK, 0); ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_NUML)); ASSERT_EQ(AMETA_NONE, mapper1.getMetaState()); ASSERT_EQ(AMETA_NONE, mapper2.getMetaState()); // Toggle caps lock on and off. process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_CAPSLOCK, 1); process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_CAPSLOCK, 0); ASSERT_TRUE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_CAPSL)); ASSERT_EQ(AMETA_CAPS_LOCK_ON, mapper1.getMetaState()); ASSERT_EQ(AMETA_CAPS_LOCK_ON, mapper2.getMetaState()); process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_CAPSLOCK, 1); process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_CAPSLOCK, 0); ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_CAPSL)); ASSERT_EQ(AMETA_NONE, mapper1.getMetaState()); ASSERT_EQ(AMETA_NONE, mapper2.getMetaState()); // Toggle scroll lock on and off. process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_SCROLLLOCK, 1); process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_SCROLLLOCK, 0); ASSERT_TRUE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_SCROLLL)); ASSERT_EQ(AMETA_SCROLL_LOCK_ON, mapper1.getMetaState()); ASSERT_EQ(AMETA_SCROLL_LOCK_ON, mapper2.getMetaState()); process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_SCROLLLOCK, 1); process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_SCROLLLOCK, 0); ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_SCROLLL)); ASSERT_EQ(AMETA_NONE, mapper1.getMetaState()); ASSERT_EQ(AMETA_NONE, mapper2.getMetaState()); } // --- KeyboardInputMapperTest_ExternalDevice --- class KeyboardInputMapperTest_ExternalDevice : public InputMapperTest { Loading services/surfaceflinger/SurfaceFlinger.cpp +12 −12 Original line number Diff line number Diff line Loading @@ -2730,12 +2730,12 @@ void SurfaceFlinger::processDisplayHotplugEventsLocked() { } const auto displayId = info->id; const auto it = mPhysicalDisplayTokens.find(displayId); const auto token = mPhysicalDisplayTokens.get(displayId); if (event.connection == hal::Connection::CONNECTED) { auto [supportedModes, activeMode] = loadDisplayModes(displayId); if (it == mPhysicalDisplayTokens.end()) { if (!token) { ALOGV("Creating display %s", to_string(displayId).c_str()); DisplayDeviceState state; Loading @@ -2750,14 +2750,13 @@ void SurfaceFlinger::processDisplayHotplugEventsLocked() { sp<IBinder> token = new BBinder(); mCurrentState.displays.add(token, state); mPhysicalDisplayTokens.emplace(displayId, std::move(token)); mPhysicalDisplayTokens.try_emplace(displayId, std::move(token)); mInterceptor->saveDisplayCreation(state); } else { ALOGV("Recreating display %s", to_string(displayId).c_str()); const auto token = it->second; auto& state = mCurrentState.displays.editValueFor(token); state.sequenceId = DisplayDeviceState{}.sequenceId; // Generate new sequenceId auto& state = mCurrentState.displays.editValueFor(token->get()); state.sequenceId = DisplayDeviceState{}.sequenceId; // Generate new sequenceId. state.physical->supportedModes = std::move(supportedModes); state.physical->activeMode = std::move(activeMode); if (getHwComposer().updatesDeviceProductInfoOnHotplugReconnect()) { Loading @@ -2767,13 +2766,13 @@ void SurfaceFlinger::processDisplayHotplugEventsLocked() { } else { ALOGV("Removing display %s", to_string(displayId).c_str()); const ssize_t index = mCurrentState.displays.indexOfKey(it->second); if (index >= 0) { if (const ssize_t index = mCurrentState.displays.indexOfKey(token->get()); index >= 0) { const DisplayDeviceState& state = mCurrentState.displays.valueAt(index); mInterceptor->saveDisplayDeletion(state.sequenceId); mCurrentState.displays.removeItemsAt(index); } mPhysicalDisplayTokens.erase(it); mPhysicalDisplayTokens.erase(displayId); } processDisplayChangesLocked(); Loading Loading @@ -2954,15 +2953,16 @@ void SurfaceFlinger::processDisplayAdded(const wp<IBinder>& displayToken, } LOG_FATAL_IF(!displaySurface); const auto display = setupNewDisplayDeviceInternal(displayToken, std::move(compositionDisplay), state, displaySurface, producer); mDisplays.emplace(displayToken, display); auto display = setupNewDisplayDeviceInternal(displayToken, std::move(compositionDisplay), state, displaySurface, producer); if (display->isPrimary()) { initScheduler(display); } if (!state.isVirtual()) { dispatchDisplayHotplugEvent(display->getPhysicalId(), true); } mDisplays.try_emplace(displayToken, std::move(display)); } void SurfaceFlinger::processDisplayRemoved(const wp<IBinder>& displayToken) { Loading services/surfaceflinger/SurfaceFlinger.h +15 −12 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ #include <android/gui/DisplayState.h> #include <cutils/atomic.h> #include <cutils/compiler.h> #include <ftl/small_map.h> #include <gui/BufferQueue.h> #include <gui/FrameTimestamps.h> #include <gui/ISurfaceComposer.h> Loading Loading @@ -905,8 +906,8 @@ private: } sp<DisplayDevice> getDisplayDeviceLocked(const wp<IBinder>& displayToken) REQUIRES(mStateLock) { const auto it = mDisplays.find(displayToken); return it == mDisplays.end() ? nullptr : it->second; const sp<DisplayDevice> nullDisplay; return mDisplays.get(displayToken).value_or(std::cref(nullDisplay)); } sp<const DisplayDevice> getDisplayDeviceLocked(PhysicalDisplayId id) const Loading Loading @@ -1051,8 +1052,8 @@ private: */ sp<IBinder> getPhysicalDisplayTokenLocked(PhysicalDisplayId displayId) const REQUIRES(mStateLock) { const auto it = mPhysicalDisplayTokens.find(displayId); return it != mPhysicalDisplayTokens.end() ? it->second : nullptr; const sp<IBinder> nullToken; return mPhysicalDisplayTokens.get(displayId).value_or(std::cref(nullToken)); } std::optional<PhysicalDisplayId> getPhysicalDisplayIdLocked( Loading Loading @@ -1247,10 +1248,14 @@ private: std::vector<HotplugEvent> mPendingHotplugEvents GUARDED_BY(mStateLock); // 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 GUARDED_BY(mStateLock); std::unordered_map<PhysicalDisplayId, sp<IBinder>> mPhysicalDisplayTokens // Displays are composited in `mDisplays` order. Internal displays are inserted at boot and // never removed, so take precedence over external and virtual displays. // // The static capacities were chosen to exceed a typical number of physical/virtual displays. // // May be read from any thread, but must only be written from the main thread. ftl::SmallMap<wp<IBinder>, const sp<DisplayDevice>, 5> mDisplays GUARDED_BY(mStateLock); ftl::SmallMap<PhysicalDisplayId, const sp<IBinder>, 3> mPhysicalDisplayTokens GUARDED_BY(mStateLock); struct { Loading Loading @@ -1423,10 +1428,8 @@ private: std::atomic<ui::Transform::RotationFlags> mActiveDisplayTransformHint; bool isRefreshRateOverlayEnabled() const REQUIRES(mStateLock) { return std::any_of(mDisplays.begin(), mDisplays.end(), [](std::pair<wp<IBinder>, sp<DisplayDevice>> display) { return display.second->isRefreshRateOverlayEnabled(); }); return hasDisplay( [](const auto& display) { return display.isRefreshRateOverlayEnabled(); }); } wp<IBinder> mActiveDisplayToken GUARDED_BY(mStateLock); Loading Loading
libs/ui/Gralloc4.cpp +5 −5 Original line number Diff line number Diff line Loading @@ -1193,10 +1193,6 @@ std::string Gralloc4Mapper::dumpBuffers(bool less) const { Gralloc4Allocator::Gralloc4Allocator(const Gralloc4Mapper& mapper) : mMapper(mapper) { mAllocator = IAllocator::getService(); if (mAllocator == nullptr) { ALOGW("allocator 4.x is not supported"); return; } if (__builtin_available(android 31, *)) { if (hasIAllocatorAidl()) { mAidlAllocator = AidlIAllocator::fromBinder(ndk::SpAIBinder( Loading @@ -1204,10 +1200,14 @@ Gralloc4Allocator::Gralloc4Allocator(const Gralloc4Mapper& mapper) : mMapper(map ALOGE_IF(!mAidlAllocator, "AIDL IAllocator declared but failed to get service"); } } if (mAllocator == nullptr && mAidlAllocator == nullptr) { ALOGW("allocator 4.x is not supported"); return; } } bool Gralloc4Allocator::isLoaded() const { return mAllocator != nullptr; return mAllocator != nullptr || mAidlAllocator != nullptr; } std::string Gralloc4Allocator::dumpDebugInfo(bool less) const { Loading
services/inputflinger/reader/mapper/KeyboardInputMapper.cpp +2 −0 Original line number Diff line number Diff line Loading @@ -428,6 +428,8 @@ void KeyboardInputMapper::initializeLedState(LedState& ledState, int32_t led) { } void KeyboardInputMapper::updateLedState(bool reset) { // Clear the local led state then union the global led state. mMetaState &= ~(AMETA_CAPS_LOCK_ON | AMETA_NUM_LOCK_ON | AMETA_SCROLL_LOCK_ON); mMetaState |= getContext()->getLedMetaState(); constexpr int32_t META_NUM = 3; Loading
services/inputflinger/tests/InputReader_test.cpp +72 −0 Original line number Diff line number Diff line Loading @@ -4007,6 +4007,78 @@ TEST_F(KeyboardInputMapperTest, Process_toggleCapsLockState) { ASSERT_EQ(AMETA_CAPS_LOCK_ON, mapper.getMetaState()); } TEST_F(KeyboardInputMapperTest, Process_LockedKeysShouldToggleInMultiDevices) { // keyboard 1. mFakeEventHub->addLed(EVENTHUB_ID, LED_CAPSL, true /*initially on*/); mFakeEventHub->addLed(EVENTHUB_ID, LED_NUML, false /*initially off*/); mFakeEventHub->addLed(EVENTHUB_ID, LED_SCROLLL, false /*initially off*/); mFakeEventHub->addKey(EVENTHUB_ID, KEY_CAPSLOCK, 0, AKEYCODE_CAPS_LOCK, 0); mFakeEventHub->addKey(EVENTHUB_ID, KEY_NUMLOCK, 0, AKEYCODE_NUM_LOCK, 0); mFakeEventHub->addKey(EVENTHUB_ID, KEY_SCROLLLOCK, 0, AKEYCODE_SCROLL_LOCK, 0); KeyboardInputMapper& mapper1 = addMapperAndConfigure<KeyboardInputMapper>(AINPUT_SOURCE_KEYBOARD, AINPUT_KEYBOARD_TYPE_ALPHABETIC); // keyboard 2. const std::string USB2 = "USB2"; const std::string DEVICE_NAME2 = "KEYBOARD2"; constexpr int32_t SECOND_DEVICE_ID = DEVICE_ID + 1; constexpr int32_t SECOND_EVENTHUB_ID = EVENTHUB_ID + 1; std::shared_ptr<InputDevice> device2 = newDevice(SECOND_DEVICE_ID, DEVICE_NAME2, USB2, SECOND_EVENTHUB_ID, ftl::Flags<InputDeviceClass>(0)); mFakeEventHub->addLed(SECOND_EVENTHUB_ID, LED_CAPSL, true /*initially on*/); mFakeEventHub->addLed(SECOND_EVENTHUB_ID, LED_NUML, false /*initially off*/); mFakeEventHub->addLed(SECOND_EVENTHUB_ID, LED_SCROLLL, false /*initially off*/); mFakeEventHub->addKey(SECOND_EVENTHUB_ID, KEY_CAPSLOCK, 0, AKEYCODE_CAPS_LOCK, 0); mFakeEventHub->addKey(SECOND_EVENTHUB_ID, KEY_NUMLOCK, 0, AKEYCODE_NUM_LOCK, 0); mFakeEventHub->addKey(SECOND_EVENTHUB_ID, KEY_SCROLLLOCK, 0, AKEYCODE_SCROLL_LOCK, 0); KeyboardInputMapper& mapper2 = device2->addMapper<KeyboardInputMapper>(SECOND_EVENTHUB_ID, AINPUT_SOURCE_KEYBOARD, AINPUT_KEYBOARD_TYPE_ALPHABETIC); device2->configure(ARBITRARY_TIME, mFakePolicy->getReaderConfiguration(), 0 /*changes*/); device2->reset(ARBITRARY_TIME); // Initial metastate is AMETA_NUM_LOCK_ON, turn it off. ASSERT_TRUE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_NUML)); ASSERT_EQ(AMETA_NUM_LOCK_ON, mapper1.getMetaState()); ASSERT_EQ(AMETA_NUM_LOCK_ON, mapper2.getMetaState()); process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_NUMLOCK, 1); process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_NUMLOCK, 0); ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_NUML)); ASSERT_EQ(AMETA_NONE, mapper1.getMetaState()); ASSERT_EQ(AMETA_NONE, mapper2.getMetaState()); // Toggle caps lock on and off. process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_CAPSLOCK, 1); process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_CAPSLOCK, 0); ASSERT_TRUE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_CAPSL)); ASSERT_EQ(AMETA_CAPS_LOCK_ON, mapper1.getMetaState()); ASSERT_EQ(AMETA_CAPS_LOCK_ON, mapper2.getMetaState()); process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_CAPSLOCK, 1); process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_CAPSLOCK, 0); ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_CAPSL)); ASSERT_EQ(AMETA_NONE, mapper1.getMetaState()); ASSERT_EQ(AMETA_NONE, mapper2.getMetaState()); // Toggle scroll lock on and off. process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_SCROLLLOCK, 1); process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_SCROLLLOCK, 0); ASSERT_TRUE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_SCROLLL)); ASSERT_EQ(AMETA_SCROLL_LOCK_ON, mapper1.getMetaState()); ASSERT_EQ(AMETA_SCROLL_LOCK_ON, mapper2.getMetaState()); process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_SCROLLLOCK, 1); process(mapper1, ARBITRARY_TIME, READ_TIME, EV_KEY, KEY_SCROLLLOCK, 0); ASSERT_FALSE(mFakeEventHub->getLedState(EVENTHUB_ID, LED_SCROLLL)); ASSERT_EQ(AMETA_NONE, mapper1.getMetaState()); ASSERT_EQ(AMETA_NONE, mapper2.getMetaState()); } // --- KeyboardInputMapperTest_ExternalDevice --- class KeyboardInputMapperTest_ExternalDevice : public InputMapperTest { Loading
services/surfaceflinger/SurfaceFlinger.cpp +12 −12 Original line number Diff line number Diff line Loading @@ -2730,12 +2730,12 @@ void SurfaceFlinger::processDisplayHotplugEventsLocked() { } const auto displayId = info->id; const auto it = mPhysicalDisplayTokens.find(displayId); const auto token = mPhysicalDisplayTokens.get(displayId); if (event.connection == hal::Connection::CONNECTED) { auto [supportedModes, activeMode] = loadDisplayModes(displayId); if (it == mPhysicalDisplayTokens.end()) { if (!token) { ALOGV("Creating display %s", to_string(displayId).c_str()); DisplayDeviceState state; Loading @@ -2750,14 +2750,13 @@ void SurfaceFlinger::processDisplayHotplugEventsLocked() { sp<IBinder> token = new BBinder(); mCurrentState.displays.add(token, state); mPhysicalDisplayTokens.emplace(displayId, std::move(token)); mPhysicalDisplayTokens.try_emplace(displayId, std::move(token)); mInterceptor->saveDisplayCreation(state); } else { ALOGV("Recreating display %s", to_string(displayId).c_str()); const auto token = it->second; auto& state = mCurrentState.displays.editValueFor(token); state.sequenceId = DisplayDeviceState{}.sequenceId; // Generate new sequenceId auto& state = mCurrentState.displays.editValueFor(token->get()); state.sequenceId = DisplayDeviceState{}.sequenceId; // Generate new sequenceId. state.physical->supportedModes = std::move(supportedModes); state.physical->activeMode = std::move(activeMode); if (getHwComposer().updatesDeviceProductInfoOnHotplugReconnect()) { Loading @@ -2767,13 +2766,13 @@ void SurfaceFlinger::processDisplayHotplugEventsLocked() { } else { ALOGV("Removing display %s", to_string(displayId).c_str()); const ssize_t index = mCurrentState.displays.indexOfKey(it->second); if (index >= 0) { if (const ssize_t index = mCurrentState.displays.indexOfKey(token->get()); index >= 0) { const DisplayDeviceState& state = mCurrentState.displays.valueAt(index); mInterceptor->saveDisplayDeletion(state.sequenceId); mCurrentState.displays.removeItemsAt(index); } mPhysicalDisplayTokens.erase(it); mPhysicalDisplayTokens.erase(displayId); } processDisplayChangesLocked(); Loading Loading @@ -2954,15 +2953,16 @@ void SurfaceFlinger::processDisplayAdded(const wp<IBinder>& displayToken, } LOG_FATAL_IF(!displaySurface); const auto display = setupNewDisplayDeviceInternal(displayToken, std::move(compositionDisplay), state, displaySurface, producer); mDisplays.emplace(displayToken, display); auto display = setupNewDisplayDeviceInternal(displayToken, std::move(compositionDisplay), state, displaySurface, producer); if (display->isPrimary()) { initScheduler(display); } if (!state.isVirtual()) { dispatchDisplayHotplugEvent(display->getPhysicalId(), true); } mDisplays.try_emplace(displayToken, std::move(display)); } void SurfaceFlinger::processDisplayRemoved(const wp<IBinder>& displayToken) { Loading
services/surfaceflinger/SurfaceFlinger.h +15 −12 Original line number Diff line number Diff line Loading @@ -27,6 +27,7 @@ #include <android/gui/DisplayState.h> #include <cutils/atomic.h> #include <cutils/compiler.h> #include <ftl/small_map.h> #include <gui/BufferQueue.h> #include <gui/FrameTimestamps.h> #include <gui/ISurfaceComposer.h> Loading Loading @@ -905,8 +906,8 @@ private: } sp<DisplayDevice> getDisplayDeviceLocked(const wp<IBinder>& displayToken) REQUIRES(mStateLock) { const auto it = mDisplays.find(displayToken); return it == mDisplays.end() ? nullptr : it->second; const sp<DisplayDevice> nullDisplay; return mDisplays.get(displayToken).value_or(std::cref(nullDisplay)); } sp<const DisplayDevice> getDisplayDeviceLocked(PhysicalDisplayId id) const Loading Loading @@ -1051,8 +1052,8 @@ private: */ sp<IBinder> getPhysicalDisplayTokenLocked(PhysicalDisplayId displayId) const REQUIRES(mStateLock) { const auto it = mPhysicalDisplayTokens.find(displayId); return it != mPhysicalDisplayTokens.end() ? it->second : nullptr; const sp<IBinder> nullToken; return mPhysicalDisplayTokens.get(displayId).value_or(std::cref(nullToken)); } std::optional<PhysicalDisplayId> getPhysicalDisplayIdLocked( Loading Loading @@ -1247,10 +1248,14 @@ private: std::vector<HotplugEvent> mPendingHotplugEvents GUARDED_BY(mStateLock); // 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 GUARDED_BY(mStateLock); std::unordered_map<PhysicalDisplayId, sp<IBinder>> mPhysicalDisplayTokens // Displays are composited in `mDisplays` order. Internal displays are inserted at boot and // never removed, so take precedence over external and virtual displays. // // The static capacities were chosen to exceed a typical number of physical/virtual displays. // // May be read from any thread, but must only be written from the main thread. ftl::SmallMap<wp<IBinder>, const sp<DisplayDevice>, 5> mDisplays GUARDED_BY(mStateLock); ftl::SmallMap<PhysicalDisplayId, const sp<IBinder>, 3> mPhysicalDisplayTokens GUARDED_BY(mStateLock); struct { Loading Loading @@ -1423,10 +1428,8 @@ private: std::atomic<ui::Transform::RotationFlags> mActiveDisplayTransformHint; bool isRefreshRateOverlayEnabled() const REQUIRES(mStateLock) { return std::any_of(mDisplays.begin(), mDisplays.end(), [](std::pair<wp<IBinder>, sp<DisplayDevice>> display) { return display.second->isRefreshRateOverlayEnabled(); }); return hasDisplay( [](const auto& display) { return display.isRefreshRateOverlayEnabled(); }); } wp<IBinder> mActiveDisplayToken GUARDED_BY(mStateLock); Loading