Feature: Exclude human Web viewing from MCP remote control sessions
Complete the bidirectional mutual exclusion between MCP remote control and human Web viewing (§8.2). Direction 1 (remote_open rejected while a human session holds the screen sub-connection) already existed; this adds direction 2: a human Web viewer is now rejected while an MCP session owns the device. Add a m_McpTriggeredDevices marker (mirroring m_MfcTriggeredDevices) that is set when an MCP session is created (BeginScreenCtrlOpen) and cleared at every session-erasure site (CloseScreenCtrlSession, SweepIdleScreenCtrl, OnScreenControlClosed, EndScreenCtrlAction), so the marker cannot go stale and permanently block humans. HandleConnect checks IsMcpTriggered before mutating client state or starting the remote desktop. Co-Authored-By: deepseek-v4-pro
This commit was merged in pull request #4.
This commit is contained in:
@@ -3851,6 +3851,10 @@ bool CMcpServer::BeginScreenCtrlOpen(uint64_t device_id, const std::string& sess
|
||||
s.sessionId = sessionId;
|
||||
s.lastActiveAt = time(nullptr);
|
||||
m_ScreenCtrlSessions[device_id] = std::move(s);
|
||||
// 双向互斥(方向二):标记该设备屏幕子连接归 MCP 会话独占,人类 Web 观看期间被拒绝
|
||||
// (HandleConnect 查 IsMcpTriggered)。会话擦除点(CloseScreenCtrlSession /
|
||||
// SweepIdleScreenCtrl / OnScreenControlClosed / EndScreenCtrlAction)同步 ClearMcpTriggered。
|
||||
WebService().SetMcpTriggered(device_id);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -3881,6 +3885,7 @@ int CMcpServer::CloseScreenCtrlSession(uint64_t device_id, const std::string& se
|
||||
}
|
||||
if (it->second.subCtx) m_ScreenCtrlContextToDevice.erase(it->second.subCtx);
|
||||
m_ScreenCtrlSessions.erase(it);
|
||||
WebService().ClearMcpTriggered(device_id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -3893,8 +3898,10 @@ int CMcpServer::SweepIdleScreenCtrl(time_t idleTimeoutSec) {
|
||||
ScreenCtrlSession& s = it->second;
|
||||
if (!s.busy && difftime(now, s.lastActiveAt) > (double)idleTimeoutSec) {
|
||||
if (s.subCtx) m_ScreenCtrlContextToDevice.erase(s.subCtx);
|
||||
toClose.push_back(it->first);
|
||||
uint64_t devId = it->first;
|
||||
toClose.push_back(devId);
|
||||
it = m_ScreenCtrlSessions.erase(it);
|
||||
WebService().ClearMcpTriggered(devId); // 锁内清除,避免与并发 remote_open 竞态
|
||||
} else {
|
||||
++it;
|
||||
}
|
||||
@@ -3921,8 +3928,10 @@ void CMcpServer::OnScreenControlClosed(context* subCtx) {
|
||||
// 注入在飞:不擦会话(注入线程仍持 subCtx),仅置 closed,由 EndScreenCtrlAction 收尾。
|
||||
sit->second.closed = true;
|
||||
} else {
|
||||
uint64_t devId = it->second;
|
||||
m_ScreenCtrlSessions.erase(sit);
|
||||
m_ScreenCtrlContextToDevice.erase(it);
|
||||
WebService().ClearMcpTriggered(devId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3954,6 +3963,7 @@ void CMcpServer::EndScreenCtrlAction(uint64_t device_id, const std::string& sess
|
||||
if (it->second.closed) { // 注入期间子连接已断:擦会话+路由
|
||||
if (it->second.subCtx) m_ScreenCtrlContextToDevice.erase(it->second.subCtx);
|
||||
m_ScreenCtrlSessions.erase(it);
|
||||
WebService().ClearMcpTriggered(device_id);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user