Loading include/input/DisplayViewport.h +37 −34 Original line number Diff line number Diff line Loading @@ -74,36 +74,40 @@ struct DisplayViewport { int32_t physicalBottom; int32_t deviceWidth; int32_t deviceHeight; bool isActive; std::string uniqueId; // The actual (hardware) port that the associated display is connected to. // Not all viewports will have this specified. std::optional<uint8_t> physicalPort; ViewportType type; DisplayViewport() : displayId(ADISPLAY_ID_NONE), orientation(DISPLAY_ORIENTATION_0), logicalLeft(0), logicalTop(0), logicalRight(0), logicalBottom(0), physicalLeft(0), physicalTop(0), physicalRight(0), physicalBottom(0), deviceWidth(0), deviceHeight(0), uniqueId(), physicalPort(std::nullopt), type(ViewportType::VIEWPORT_INTERNAL) { } DisplayViewport() : displayId(ADISPLAY_ID_NONE), orientation(DISPLAY_ORIENTATION_0), logicalLeft(0), logicalTop(0), logicalRight(0), logicalBottom(0), physicalLeft(0), physicalTop(0), physicalRight(0), physicalBottom(0), deviceWidth(0), deviceHeight(0), isActive(false), uniqueId(), physicalPort(std::nullopt), type(ViewportType::VIEWPORT_INTERNAL) {} bool operator==(const DisplayViewport& other) const { return displayId == other.displayId && orientation == other.orientation && logicalLeft == other.logicalLeft && logicalTop == other.logicalTop && logicalRight == other.logicalRight && logicalBottom == other.logicalBottom && physicalLeft == other.physicalLeft && physicalTop == other.physicalTop && physicalRight == other.physicalRight && physicalBottom == other.physicalBottom && deviceWidth == other.deviceWidth && deviceHeight == other.deviceHeight && uniqueId == other.uniqueId && physicalPort == other.physicalPort && type == other.type; return displayId == other.displayId && orientation == other.orientation && logicalLeft == other.logicalLeft && logicalTop == other.logicalTop && logicalRight == other.logicalRight && logicalBottom == other.logicalBottom && physicalLeft == other.physicalLeft && physicalTop == other.physicalTop && physicalRight == other.physicalRight && physicalBottom == other.physicalBottom && deviceWidth == other.deviceWidth && deviceHeight == other.deviceHeight && isActive == other.isActive && uniqueId == other.uniqueId && physicalPort == other.physicalPort && type == other.type; } bool operator!=(const DisplayViewport& other) const { Loading @@ -127,6 +131,7 @@ struct DisplayViewport { physicalBottom = height; deviceWidth = width; deviceHeight = height; isActive = false; uniqueId.clear(); physicalPort = std::nullopt; type = ViewportType::VIEWPORT_INTERNAL; Loading @@ -136,16 +141,14 @@ struct DisplayViewport { return StringPrintf("Viewport %s: displayId=%d, uniqueId=%s, port=%s, orientation=%d, " "logicalFrame=[%d, %d, %d, %d], " "physicalFrame=[%d, %d, %d, %d], " "deviceSize=[%d, %d]", viewportTypeToString(type), displayId, uniqueId.c_str(), physicalPort ? StringPrintf("%" PRIu8, *physicalPort).c_str() : "<none>", orientation, logicalLeft, logicalTop, logicalRight, logicalBottom, physicalLeft, physicalTop, physicalRight, physicalBottom, deviceWidth, deviceHeight); "deviceSize=[%d, %d], " "isActive=[%d]", viewportTypeToString(type), displayId, uniqueId.c_str(), physicalPort ? StringPrintf("%" PRIu8, *physicalPort).c_str() : "<none>", orientation, logicalLeft, logicalTop, logicalRight, logicalBottom, physicalLeft, physicalTop, physicalRight, physicalBottom, deviceWidth, deviceHeight, isActive); } }; Loading libs/gralloc/types/include/gralloctypes/Gralloc4.h +6 −0 Original line number Diff line number Diff line Loading @@ -431,6 +431,12 @@ static const aidl::android::hardware::graphics::common::ExtendableType PlaneLayo static_cast<int64_t>( aidl::android::hardware::graphics::common::PlaneLayoutComponentType::A)}; static const aidl::android::hardware::graphics::common::ExtendableType PlaneLayoutComponentType_RAW = {GRALLOC4_STANDARD_PLANE_LAYOUT_COMPONENT_TYPE, static_cast<int64_t>( aidl::android::hardware::graphics::common::PlaneLayoutComponentType::RAW)}; /*---------------------------------------------------------------------------------------------*/ /** Loading services/inputflinger/dispatcher/InputDispatcher.cpp +55 −30 Original line number Diff line number Diff line Loading @@ -620,6 +620,33 @@ void InputDispatcher::dispatchOnceInnerLocked(nsecs_t* nextWakeupTime) { } } /** * Return true if the events preceding this incoming motion event should be dropped * Return false otherwise (the default behaviour) */ bool InputDispatcher::shouldPruneInboundQueueLocked(const MotionEntry& motionEntry) { bool isPointerDownEvent = motionEntry.action == AMOTION_EVENT_ACTION_DOWN && (motionEntry.source & AINPUT_SOURCE_CLASS_POINTER); if (isPointerDownEvent && mInputTargetWaitCause == INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY && mInputTargetWaitApplicationToken != nullptr) { int32_t displayId = motionEntry.displayId; int32_t x = static_cast<int32_t>( motionEntry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X)); int32_t y = static_cast<int32_t>( motionEntry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y)); sp<InputWindowHandle> touchedWindowHandle = findTouchedWindowAtLocked(displayId, x, y); if (touchedWindowHandle != nullptr && touchedWindowHandle->getApplicationToken() != mInputTargetWaitApplicationToken) { // User touched a different application than the one we are waiting on. // Flag the event, and start pruning the input queue. ALOGI("Pruning input queue because user touched a different application"); return true; } } return false; } bool InputDispatcher::enqueueInboundEventLocked(EventEntry* entry) { bool needWake = mInboundQueue.empty(); mInboundQueue.push_back(entry); Loading Loading @@ -653,32 +680,18 @@ bool InputDispatcher::enqueueInboundEventLocked(EventEntry* entry) { // decides to touch a window in a different application. // If the application takes too long to catch up then we drop all events preceding // the touch into the other window. MotionEntry* motionEntry = static_cast<MotionEntry*>(entry); if (motionEntry->action == AMOTION_EVENT_ACTION_DOWN && (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) && mInputTargetWaitCause == INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY && mInputTargetWaitApplicationToken != nullptr) { int32_t displayId = motionEntry->displayId; int32_t x = int32_t(motionEntry->pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X)); int32_t y = int32_t(motionEntry->pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y)); sp<InputWindowHandle> touchedWindowHandle = findTouchedWindowAtLocked(displayId, x, y); if (touchedWindowHandle != nullptr && touchedWindowHandle->getApplicationToken() != mInputTargetWaitApplicationToken) { // User touched a different application than the one we are waiting on. // Flag the event, and start pruning the input queue. mNextUnblockedEvent = motionEntry; if (shouldPruneInboundQueueLocked(static_cast<MotionEntry&>(*entry))) { mNextUnblockedEvent = entry; needWake = true; } break; } case EventEntry::Type::FOCUS: { LOG_ALWAYS_FATAL("Focus events should be inserted using enqueueFocusEventLocked"); break; } case EventEntry::Type::CONFIGURATION_CHANGED: case EventEntry::Type::DEVICE_RESET: case EventEntry::Type::FOCUS: { case EventEntry::Type::DEVICE_RESET: { // nothing to do break; } Loading Loading @@ -980,9 +993,24 @@ bool InputDispatcher::dispatchDeviceResetLocked(nsecs_t currentTime, DeviceReset } void InputDispatcher::enqueueFocusEventLocked(const InputWindowHandle& window, bool hasFocus) { if (mPendingEvent != nullptr) { // Move the pending event to the front of the queue. This will give the chance // for the pending event to get dispatched to the newly focused window mInboundQueue.push_front(mPendingEvent); mPendingEvent = nullptr; } FocusEntry* focusEntry = new FocusEntry(mIdGenerator.nextId(), now(), window.getToken(), hasFocus); enqueueInboundEventLocked(focusEntry); // This event should go to the front of the queue, but behind all other focus events // Find the last focus event, and insert right after it std::deque<EventEntry*>::reverse_iterator it = std::find_if(mInboundQueue.rbegin(), mInboundQueue.rend(), [](EventEntry* event) { return event->type == EventEntry::Type::FOCUS; }); // Maintain the order of focus events. Insert the entry after all other focus events. mInboundQueue.insert(it.base(), focusEntry); } void InputDispatcher::dispatchFocusLocked(nsecs_t currentTime, FocusEntry* entry) { Loading Loading @@ -2108,15 +2136,12 @@ std::string InputDispatcher::getApplicationWindowLabel( const sp<InputWindowHandle>& windowHandle) { if (applicationHandle != nullptr) { if (windowHandle != nullptr) { std::string label(applicationHandle->getName()); label += " - "; label += windowHandle->getName(); return label; return applicationHandle->getName() + " - " + windowHandle->getName(); } else { return applicationHandle->getName(); } } else if (windowHandle != nullptr) { return windowHandle->getName(); return windowHandle->getInfo()->applicationInfo.name + " - " + windowHandle->getName(); } else { return "<unknown application or window>"; } Loading Loading @@ -4620,7 +4645,7 @@ void InputDispatcher::doDispatchCycleFinishedLockedInterruptible(CommandEntry* c } DispatchEntry* dispatchEntry = *dispatchEntryIt; nsecs_t eventDuration = finishTime - dispatchEntry->deliveryTime; const nsecs_t eventDuration = finishTime - dispatchEntry->deliveryTime; if (eventDuration > SLOW_EVENT_PROCESSING_WARNING_TIMEOUT) { std::string msg = StringPrintf("Window '%s' spent %0.1fms processing the last input event: ", Loading @@ -4644,7 +4669,7 @@ void InputDispatcher::doDispatchCycleFinishedLockedInterruptible(CommandEntry* c } // Dequeue the event and start the next cycle. // Note that because the lock might have been released, it is possible that the // Because the lock might have been released, it is possible that the // contents of the wait queue to have been drained, so we need to double-check // a few things. dispatchEntryIt = connection->findWaitQueueEntry(seq); Loading services/inputflinger/dispatcher/InputDispatcher.h +2 −0 Original line number Diff line number Diff line Loading @@ -345,6 +345,8 @@ private: bool mInputTargetWaitTimeoutExpired GUARDED_BY(mLock); sp<IBinder> mInputTargetWaitApplicationToken GUARDED_BY(mLock); bool shouldPruneInboundQueueLocked(const MotionEntry& motionEntry) REQUIRES(mLock); // Contains the last window which received a hover event. sp<InputWindowHandle> mLastHoverWindowHandle GUARDED_BY(mLock); Loading services/surfaceflinger/BufferLayerConsumer.cpp +14 −0 Original line number Diff line number Diff line Loading @@ -452,6 +452,13 @@ void BufferLayerConsumer::freeBufferLocked(int slotIndex) { } void BufferLayerConsumer::onDisconnect() { Mutex::Autolock lock(mMutex); if (mAbandoned) { // Nothing to do if we're already abandoned. return; } mLayer->onDisconnect(); } Loading Loading @@ -486,6 +493,13 @@ void BufferLayerConsumer::onBufferAvailable(const BufferItem& item) { void BufferLayerConsumer::addAndGetFrameTimestamps(const NewFrameEventsEntry* newTimestamps, FrameEventHistoryDelta* outDelta) { Mutex::Autolock lock(mMutex); if (mAbandoned) { // Nothing to do if we're already abandoned. return; } mLayer->addAndGetFrameTimestamps(newTimestamps, outDelta); } Loading Loading
include/input/DisplayViewport.h +37 −34 Original line number Diff line number Diff line Loading @@ -74,36 +74,40 @@ struct DisplayViewport { int32_t physicalBottom; int32_t deviceWidth; int32_t deviceHeight; bool isActive; std::string uniqueId; // The actual (hardware) port that the associated display is connected to. // Not all viewports will have this specified. std::optional<uint8_t> physicalPort; ViewportType type; DisplayViewport() : displayId(ADISPLAY_ID_NONE), orientation(DISPLAY_ORIENTATION_0), logicalLeft(0), logicalTop(0), logicalRight(0), logicalBottom(0), physicalLeft(0), physicalTop(0), physicalRight(0), physicalBottom(0), deviceWidth(0), deviceHeight(0), uniqueId(), physicalPort(std::nullopt), type(ViewportType::VIEWPORT_INTERNAL) { } DisplayViewport() : displayId(ADISPLAY_ID_NONE), orientation(DISPLAY_ORIENTATION_0), logicalLeft(0), logicalTop(0), logicalRight(0), logicalBottom(0), physicalLeft(0), physicalTop(0), physicalRight(0), physicalBottom(0), deviceWidth(0), deviceHeight(0), isActive(false), uniqueId(), physicalPort(std::nullopt), type(ViewportType::VIEWPORT_INTERNAL) {} bool operator==(const DisplayViewport& other) const { return displayId == other.displayId && orientation == other.orientation && logicalLeft == other.logicalLeft && logicalTop == other.logicalTop && logicalRight == other.logicalRight && logicalBottom == other.logicalBottom && physicalLeft == other.physicalLeft && physicalTop == other.physicalTop && physicalRight == other.physicalRight && physicalBottom == other.physicalBottom && deviceWidth == other.deviceWidth && deviceHeight == other.deviceHeight && uniqueId == other.uniqueId && physicalPort == other.physicalPort && type == other.type; return displayId == other.displayId && orientation == other.orientation && logicalLeft == other.logicalLeft && logicalTop == other.logicalTop && logicalRight == other.logicalRight && logicalBottom == other.logicalBottom && physicalLeft == other.physicalLeft && physicalTop == other.physicalTop && physicalRight == other.physicalRight && physicalBottom == other.physicalBottom && deviceWidth == other.deviceWidth && deviceHeight == other.deviceHeight && isActive == other.isActive && uniqueId == other.uniqueId && physicalPort == other.physicalPort && type == other.type; } bool operator!=(const DisplayViewport& other) const { Loading @@ -127,6 +131,7 @@ struct DisplayViewport { physicalBottom = height; deviceWidth = width; deviceHeight = height; isActive = false; uniqueId.clear(); physicalPort = std::nullopt; type = ViewportType::VIEWPORT_INTERNAL; Loading @@ -136,16 +141,14 @@ struct DisplayViewport { return StringPrintf("Viewport %s: displayId=%d, uniqueId=%s, port=%s, orientation=%d, " "logicalFrame=[%d, %d, %d, %d], " "physicalFrame=[%d, %d, %d, %d], " "deviceSize=[%d, %d]", viewportTypeToString(type), displayId, uniqueId.c_str(), physicalPort ? StringPrintf("%" PRIu8, *physicalPort).c_str() : "<none>", orientation, logicalLeft, logicalTop, logicalRight, logicalBottom, physicalLeft, physicalTop, physicalRight, physicalBottom, deviceWidth, deviceHeight); "deviceSize=[%d, %d], " "isActive=[%d]", viewportTypeToString(type), displayId, uniqueId.c_str(), physicalPort ? StringPrintf("%" PRIu8, *physicalPort).c_str() : "<none>", orientation, logicalLeft, logicalTop, logicalRight, logicalBottom, physicalLeft, physicalTop, physicalRight, physicalBottom, deviceWidth, deviceHeight, isActive); } }; Loading
libs/gralloc/types/include/gralloctypes/Gralloc4.h +6 −0 Original line number Diff line number Diff line Loading @@ -431,6 +431,12 @@ static const aidl::android::hardware::graphics::common::ExtendableType PlaneLayo static_cast<int64_t>( aidl::android::hardware::graphics::common::PlaneLayoutComponentType::A)}; static const aidl::android::hardware::graphics::common::ExtendableType PlaneLayoutComponentType_RAW = {GRALLOC4_STANDARD_PLANE_LAYOUT_COMPONENT_TYPE, static_cast<int64_t>( aidl::android::hardware::graphics::common::PlaneLayoutComponentType::RAW)}; /*---------------------------------------------------------------------------------------------*/ /** Loading
services/inputflinger/dispatcher/InputDispatcher.cpp +55 −30 Original line number Diff line number Diff line Loading @@ -620,6 +620,33 @@ void InputDispatcher::dispatchOnceInnerLocked(nsecs_t* nextWakeupTime) { } } /** * Return true if the events preceding this incoming motion event should be dropped * Return false otherwise (the default behaviour) */ bool InputDispatcher::shouldPruneInboundQueueLocked(const MotionEntry& motionEntry) { bool isPointerDownEvent = motionEntry.action == AMOTION_EVENT_ACTION_DOWN && (motionEntry.source & AINPUT_SOURCE_CLASS_POINTER); if (isPointerDownEvent && mInputTargetWaitCause == INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY && mInputTargetWaitApplicationToken != nullptr) { int32_t displayId = motionEntry.displayId; int32_t x = static_cast<int32_t>( motionEntry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X)); int32_t y = static_cast<int32_t>( motionEntry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y)); sp<InputWindowHandle> touchedWindowHandle = findTouchedWindowAtLocked(displayId, x, y); if (touchedWindowHandle != nullptr && touchedWindowHandle->getApplicationToken() != mInputTargetWaitApplicationToken) { // User touched a different application than the one we are waiting on. // Flag the event, and start pruning the input queue. ALOGI("Pruning input queue because user touched a different application"); return true; } } return false; } bool InputDispatcher::enqueueInboundEventLocked(EventEntry* entry) { bool needWake = mInboundQueue.empty(); mInboundQueue.push_back(entry); Loading Loading @@ -653,32 +680,18 @@ bool InputDispatcher::enqueueInboundEventLocked(EventEntry* entry) { // decides to touch a window in a different application. // If the application takes too long to catch up then we drop all events preceding // the touch into the other window. MotionEntry* motionEntry = static_cast<MotionEntry*>(entry); if (motionEntry->action == AMOTION_EVENT_ACTION_DOWN && (motionEntry->source & AINPUT_SOURCE_CLASS_POINTER) && mInputTargetWaitCause == INPUT_TARGET_WAIT_CAUSE_APPLICATION_NOT_READY && mInputTargetWaitApplicationToken != nullptr) { int32_t displayId = motionEntry->displayId; int32_t x = int32_t(motionEntry->pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X)); int32_t y = int32_t(motionEntry->pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y)); sp<InputWindowHandle> touchedWindowHandle = findTouchedWindowAtLocked(displayId, x, y); if (touchedWindowHandle != nullptr && touchedWindowHandle->getApplicationToken() != mInputTargetWaitApplicationToken) { // User touched a different application than the one we are waiting on. // Flag the event, and start pruning the input queue. mNextUnblockedEvent = motionEntry; if (shouldPruneInboundQueueLocked(static_cast<MotionEntry&>(*entry))) { mNextUnblockedEvent = entry; needWake = true; } break; } case EventEntry::Type::FOCUS: { LOG_ALWAYS_FATAL("Focus events should be inserted using enqueueFocusEventLocked"); break; } case EventEntry::Type::CONFIGURATION_CHANGED: case EventEntry::Type::DEVICE_RESET: case EventEntry::Type::FOCUS: { case EventEntry::Type::DEVICE_RESET: { // nothing to do break; } Loading Loading @@ -980,9 +993,24 @@ bool InputDispatcher::dispatchDeviceResetLocked(nsecs_t currentTime, DeviceReset } void InputDispatcher::enqueueFocusEventLocked(const InputWindowHandle& window, bool hasFocus) { if (mPendingEvent != nullptr) { // Move the pending event to the front of the queue. This will give the chance // for the pending event to get dispatched to the newly focused window mInboundQueue.push_front(mPendingEvent); mPendingEvent = nullptr; } FocusEntry* focusEntry = new FocusEntry(mIdGenerator.nextId(), now(), window.getToken(), hasFocus); enqueueInboundEventLocked(focusEntry); // This event should go to the front of the queue, but behind all other focus events // Find the last focus event, and insert right after it std::deque<EventEntry*>::reverse_iterator it = std::find_if(mInboundQueue.rbegin(), mInboundQueue.rend(), [](EventEntry* event) { return event->type == EventEntry::Type::FOCUS; }); // Maintain the order of focus events. Insert the entry after all other focus events. mInboundQueue.insert(it.base(), focusEntry); } void InputDispatcher::dispatchFocusLocked(nsecs_t currentTime, FocusEntry* entry) { Loading Loading @@ -2108,15 +2136,12 @@ std::string InputDispatcher::getApplicationWindowLabel( const sp<InputWindowHandle>& windowHandle) { if (applicationHandle != nullptr) { if (windowHandle != nullptr) { std::string label(applicationHandle->getName()); label += " - "; label += windowHandle->getName(); return label; return applicationHandle->getName() + " - " + windowHandle->getName(); } else { return applicationHandle->getName(); } } else if (windowHandle != nullptr) { return windowHandle->getName(); return windowHandle->getInfo()->applicationInfo.name + " - " + windowHandle->getName(); } else { return "<unknown application or window>"; } Loading Loading @@ -4620,7 +4645,7 @@ void InputDispatcher::doDispatchCycleFinishedLockedInterruptible(CommandEntry* c } DispatchEntry* dispatchEntry = *dispatchEntryIt; nsecs_t eventDuration = finishTime - dispatchEntry->deliveryTime; const nsecs_t eventDuration = finishTime - dispatchEntry->deliveryTime; if (eventDuration > SLOW_EVENT_PROCESSING_WARNING_TIMEOUT) { std::string msg = StringPrintf("Window '%s' spent %0.1fms processing the last input event: ", Loading @@ -4644,7 +4669,7 @@ void InputDispatcher::doDispatchCycleFinishedLockedInterruptible(CommandEntry* c } // Dequeue the event and start the next cycle. // Note that because the lock might have been released, it is possible that the // Because the lock might have been released, it is possible that the // contents of the wait queue to have been drained, so we need to double-check // a few things. dispatchEntryIt = connection->findWaitQueueEntry(seq); Loading
services/inputflinger/dispatcher/InputDispatcher.h +2 −0 Original line number Diff line number Diff line Loading @@ -345,6 +345,8 @@ private: bool mInputTargetWaitTimeoutExpired GUARDED_BY(mLock); sp<IBinder> mInputTargetWaitApplicationToken GUARDED_BY(mLock); bool shouldPruneInboundQueueLocked(const MotionEntry& motionEntry) REQUIRES(mLock); // Contains the last window which received a hover event. sp<InputWindowHandle> mLastHoverWindowHandle GUARDED_BY(mLock); Loading
services/surfaceflinger/BufferLayerConsumer.cpp +14 −0 Original line number Diff line number Diff line Loading @@ -452,6 +452,13 @@ void BufferLayerConsumer::freeBufferLocked(int slotIndex) { } void BufferLayerConsumer::onDisconnect() { Mutex::Autolock lock(mMutex); if (mAbandoned) { // Nothing to do if we're already abandoned. return; } mLayer->onDisconnect(); } Loading Loading @@ -486,6 +493,13 @@ void BufferLayerConsumer::onBufferAvailable(const BufferItem& item) { void BufferLayerConsumer::addAndGetFrameTimestamps(const NewFrameEventsEntry* newTimestamps, FrameEventHistoryDelta* outDelta) { Mutex::Autolock lock(mMutex); if (mAbandoned) { // Nothing to do if we're already abandoned. return; } mLayer->addAndGetFrameTimestamps(newTimestamps, outDelta); } Loading