Repository navigation
fix: restore the power mode from the active session only - #236
Conversation
Reviewer's GuidePower-mode recovery is now tracked as pending and performed only by the active session, with race-safe activity checks and target comparisons preventing background-session and redundant writes. Sequence diagram for deferred power-mode recoverysequenceDiagram
participant Power as Power1
participant Session as SessionManager
participant Logind as login1 Session
Power->>Session: PrepareForSleep(false)
Session->>Session: m_powerModeRecoveryPending = true
Session->>Logind: active()
Logind-->>Session: false
Note over Session: Recovery deferred
Logind->>Session: ActiveChanged(true)
Session->>Logind: active()
Logind-->>Session: true
Session->>Power: Get power properties
Power-->>Session: Current mode and battery state
Session->>Logind: active()
Logind-->>Session: true
alt target differs from tlpMode
Session->>Power: setTlpMode(target)
else target already matches
Note over Session: Clear pending flag without writing
end
State diagram for pending power-mode recoverystateDiagram-v2
[*] --> Idle
Idle --> Pending: PrepareForSleep(false)
Idle --> Pending: SessionManager init
Pending --> Pending: ActiveChanged(false)
Pending --> Reading: ActiveChanged(true)
Reading --> Pending: becomes inactive
Reading --> Idle: target matches current mode
Reading --> Idle: active and target differs / setTlpMode
Idle --> Idle: ActiveChanged(true) without pending flag
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
1. Gate the recovery on the active login1 session, so a background session no longer writes the global power mode when the system resumes. 2. Run the recovery from the wakeup handler and from ActiveChanged(true); the active check inside makes the order of those signals irrelevant. 3. Keep the write idempotent: skip it when the target mode already matches, and re-check activity after reading the power properties. Log: Stop background sessions from writing the global power mode Influence: 1. Log in as user A, switch to user B and hibernate; after resume switch back to A and confirm no password dialog is left on the lock screen. 2. Confirm the background session issues no SetTlpMode on wakeup (the user journal shows no attempt). 3. In the active session, wake up with a configured mode different from the applied one and confirm the mode is restored exactly once. 4. With low battery and powersave as the target, confirm the low battery mode is written once and not written again afterwards. fix: 仅由活动会话恢复电源模式 1. 恢复前判断当前会话是否为活动会话,后台会话在系统唤醒时不再写入 全局电源模式。 2. 唤醒处理与 ActiveChanged(true) 都会调用恢复;内部的 active 判断 使这两个信号的先后顺序不影响结果。 3. 写入保持幂等:目标模式与当前一致时跳过;读取电源属性后再次校验 会话活动状态。 Log: 避免后台会话写入全局电源模式 Influence: 1. 用户A登录后切到用户B休眠,唤醒后切回A,确认锁屏不再残留密码 认证弹窗。 2. 确认后台会话唤醒时不调用 SetTlpMode(用户日志无相关尝试)。 3. 活动会话唤醒且配置模式与已应用模式不同时,确认模式只被恢复一次。 4. 低电量且目标为节能模式时,确认 lowBattery 写入一次且不重复写入。 PMS: BUG-379055
217e466 to
e18a182
Compare
deepin pr auto review🤖 AI 代码审查报告📊 总体评价
🔍 详细分析1. 语法逻辑 ✅评价: 优秀 ✅ 通过 潜在问题: 建议: 语法正确,逻辑清晰,无需修改 2. 代码质量 ✅评价: 优秀 ✅ 通过 潜在问题: 建议: 建议后续为 SessionManager 的电源模式恢复逻辑添加永久单元测试,确保回归安全性 3. 代码性能 ✅评价: 优秀 ✅ 通过 潜在问题: 建议: 当前实现在模式匹配时提前返回,已最小化不必要的 DBus 调用。如后续出现性能瓶颈,可考虑异步读取属性或缓存上次读取结果 4. 代码安全 🔒评价: 优秀 ✅ 通过
安全漏洞详情: 建议: 无安全漏洞。本次变更实际上提升了安全性,通过限制只有活动会话才能写入系统级电源模式,避免了非活动会话触发 polkit 管理员密码弹窗的安全隐患 💡 改进建议代码示例// 当前代码已无需修复,以下为代码审查中确认的正确实现
void SessionManager::recoverySystemPowerMode()
{
// 电源模式是系统级的,只有活动会话可以恢复,否则会与活动会话冲突
if (!m_login1SessionInter->active())
return;
// ... 读取 DBus 属性 ...
if (mode == tlpMode)
return;
// ... 电池状态检查 ...
if (mode == tlpMode)
return;
// 读取属性期间会话可能已变为非活动,等下次激活时再恢复
if (!m_login1SessionInter->active())
return;
setTlpMode(mode);
}本报告由 AI 代码审查工具自动生成 |
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: fly602, mhduiy The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
On resume
SessionManagerrestored the system power mode from thePrepareForSleep(false)handler in every logged in session. The power mode issystem wide, so a background session wrote a mode it did not own, and because that
write comes from a session that is not the active one, polkit asks for an
administrator password instead of granting it (
allow_inactiveisauth_adminwhile
allow_activeisyes).Reported case: two logged in users, hibernate from user A, resume, switch to user B.
B's session had written the global power mode from the background and B's lock
screen showed an administrator password dialog.
This change keeps the intent (the mode configured before suspend is restored) but
restricts who may do it:
session;
ActiveChanged(true), so theorder of those two signals does not matter;
and the activity state is re-checked after the power properties were read.
Verification
The state machine was exercised with the real
SessionManageragainst an isolatedD-Bus with stub login1/Power1 services:
PrepareForSleep(false)SetTlpMode()issuedpowersavetargetpowersavewrittenlowBatterywritten onceNo permanent test target was added: this repository has no harness for the session
manager (the existing
securityloaderhelper_testis not built by default), so thebehaviour was verified with a throwaway harness instead.
debian/changelogis intentionally not touched; the version bump is generated by theupdate-changelog workflow (upstream, only
chore: bump version to ...commits changeit).
Note: the recovery now runs on every activation, so the synchronous property reads
happen on each session switch. They use
QDBusInterface's default timeout, asbefore, and return early when the mode already matches.
Passwordless registration for the power service callers is a separate fix in
dde-services.
Summary by Sourcery
Restore the pre-suspend power mode only from the active session and make recovery safe across wakeup and session-activation events.
Bug Fixes: