From f79bb607eb9946f6bd736fa7628ec4463181f04c Mon Sep 17 00:00:00 2001 From: zhangkun Date: Mon, 17 Aug 2026 10:15:29 +0800 Subject: [PATCH] feat(power): hand service to dde-services MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. Remove legacy session and system Power implementations and registration. 2. Remove migrated Power assets from dde-daemon packaging. 3. Remove Daemon1 idle and screen APIs while retaining sleep handling in power.go. 4. Route legacy session Power and keybinding callers to system Power1. 5. Remove obsolete Power authorization actions and in-process module coupling. 6. Require dde-services newer than 1.0.41 as the sole Power1 owner. Log: Transfer Power service ownership and callers to dde-services. Influence: Power1 runs only from dde-services after upgrade. feat(power): 将服务移交 dde-services 1. 删除 dde-daemon 中旧的会话与系统 Power 实现及注册入口。 2. 从 dde-daemon 打包中移除已迁移的 Power 资源。 3. 删除 Daemon1 空闲和屏幕接口,在 power.go 中保留睡眠处理。 4. 将旧会话 Power 和快捷键调用方切换到系统 Power1。 5. 删除废弃的 Power 鉴权动作及进程内模块耦合。 6. 要求由高于 1.0.41 的 dde-services 单独提供 Power1。 Log: 将 Power 服务所有权和调用方移交至 dde-services。 PMS: TASK-394241 Influence: 升级后 Power1 仅由 dde-services 运行。 Change-Id: If604d29ceefa681e7054ec0b2f62c498fc791950 --- Makefile | 6 +- bin/dde-session-daemon/daemon.go | 1 - bin/dde-session-daemon/main.go | 2 +- bin/dde-session-daemon/module.go | 1 - .../exported_methods_auto.go | 10 - bin/dde-system-daemon/main.go | 35 +- bin/dde-system-daemon/power.go | 200 --- bin/dde-system-daemon/power_test.go | 237 --- debian/control | 2 +- keybinding1/utils.go | 8 +- .../org.deepin.dde.hardware-control.policy.in | 21 - session/power1/constant.go | 84 - session/power1/count_ticker.go | 62 - session/power1/daemon.go | 89 - session/power1/delayed_task.go | 87 - session/power1/exported_methods_auto.go | 29 - session/power1/helper.go | 107 -- session/power1/lid_switch.go | 188 -- session/power1/manager.go | 1574 ----------------- session/power1/manager_events.go | 333 ---- session/power1/manager_stub.go | 62 - session/power1/power_dbusutil.go | 380 ---- session/power1/power_save_plan.go | 1199 ------------- session/power1/power_test.go | 194 -- session/power1/sleep_inhibit.go | 164 -- session/power1/submodule.go | 59 - session/power1/sync_config.go | 37 - session/power1/utils.go | 772 -------- session/power1/warn_level.go | 97 - session/power1/warn_level_config.go | 195 -- system/power1/battery.go | 277 --- system/power1/battery_display.go | 151 -- system/power1/battery_display_test.go | 45 - system/power1/battery_history.go | 37 - system/power1/battery_history_test.go | 43 - system/power1/battery_test.go | 30 - system/power1/daemon.go | 202 --- system/power1/exported_methods_auto.go | 62 - system/power1/lid_switch.go | 48 - system/power1/lid_switch_common.go | 236 --- system/power1/lid_switch_common_test.go | 67 - system/power1/lid_switch_sw.go | 65 - system/power1/manager.go | 921 ---------- system/power1/manager_ifc.go | 154 -- system/power1/manager_powersave.go | 153 -- system/power1/power_dbusutil.go | 514 ------ system/power1/power_key_edit.go | 38 - system/power1/power_key_edit_test.go | 33 - system/power1/power_test.go | 57 - .../testdata/scaling_available_governors | 1 - system/power1/testdata/scaling_governor | 1 - system/power1/testdata/scaling_governor2 | 0 .../testdata/setGovernor/scaling_governor | 1 - 53 files changed, 22 insertions(+), 9349 deletions(-) delete mode 100644 bin/dde-system-daemon/power_test.go delete mode 100644 session/power1/constant.go delete mode 100644 session/power1/count_ticker.go delete mode 100644 session/power1/daemon.go delete mode 100644 session/power1/delayed_task.go delete mode 100644 session/power1/exported_methods_auto.go delete mode 100644 session/power1/helper.go delete mode 100644 session/power1/lid_switch.go delete mode 100644 session/power1/manager.go delete mode 100644 session/power1/manager_events.go delete mode 100644 session/power1/manager_stub.go delete mode 100644 session/power1/power_dbusutil.go delete mode 100644 session/power1/power_save_plan.go delete mode 100644 session/power1/power_test.go delete mode 100644 session/power1/sleep_inhibit.go delete mode 100644 session/power1/submodule.go delete mode 100644 session/power1/sync_config.go delete mode 100644 session/power1/utils.go delete mode 100644 session/power1/warn_level.go delete mode 100644 session/power1/warn_level_config.go delete mode 100644 system/power1/battery.go delete mode 100644 system/power1/battery_display.go delete mode 100644 system/power1/battery_display_test.go delete mode 100644 system/power1/battery_history.go delete mode 100644 system/power1/battery_history_test.go delete mode 100644 system/power1/battery_test.go delete mode 100644 system/power1/daemon.go delete mode 100644 system/power1/exported_methods_auto.go delete mode 100644 system/power1/lid_switch.go delete mode 100644 system/power1/lid_switch_common.go delete mode 100644 system/power1/lid_switch_common_test.go delete mode 100644 system/power1/lid_switch_sw.go delete mode 100644 system/power1/manager.go delete mode 100644 system/power1/manager_ifc.go delete mode 100644 system/power1/manager_powersave.go delete mode 100644 system/power1/power_dbusutil.go delete mode 100644 system/power1/power_key_edit.go delete mode 100644 system/power1/power_key_edit_test.go delete mode 100644 system/power1/power_test.go delete mode 100644 system/power1/testdata/scaling_available_governors delete mode 100644 system/power1/testdata/scaling_governor delete mode 100644 system/power1/testdata/scaling_governor2 delete mode 100644 system/power1/testdata/setGovernor/scaling_governor diff --git a/Makefile b/Makefile index 83cb08811..746a75b76 100644 --- a/Makefile +++ b/Makefile @@ -64,7 +64,6 @@ TEST = \ ${GOPKG_PREFIX}/service_trigger \ ${GOPKG_PREFIX}/session/common \ ${GOPKG_PREFIX}/session/eventlog \ - ${GOPKG_PREFIX}/session/power1 \ ${GOPKG_PREFIX}/sessionwatcher1 \ ${GOPKG_PREFIX}/soundeffect1 \ ${GOPKG_PREFIX}/system/airplane_mode1 \ @@ -75,7 +74,6 @@ TEST = \ ${GOPKG_PREFIX}/system/inputdevices1 \ ${GOPKG_PREFIX}/system/keyevent1 \ ${GOPKG_PREFIX}/system/lang \ - ${GOPKG_PREFIX}/system/power1 \ ${GOPKG_PREFIX}/system/resource_ctl \ ${GOPKG_PREFIX}/system/scheduler \ ${GOPKG_PREFIX}/system/swapsched1 \ @@ -183,13 +181,16 @@ install: build install-dde-data install-icons mkdir -pv ${DESTDIR}${PREFIX}/share/dbus-1/system.d cp misc/conf/*.conf ${DESTDIR}${PREFIX}/share/dbus-1/system.d/ + rm -f ${DESTDIR}${PREFIX}/share/dbus-1/system.d/org.deepin.dde.Power1.conf mkdir -pv ${DESTDIR}${PREFIX}/share/dbus-1 cp -r misc/services ${DESTDIR}${PREFIX}/share/dbus-1/ cp -r misc/system-services ${DESTDIR}${PREFIX}/share/dbus-1/ + rm -f ${DESTDIR}${PREFIX}/share/dbus-1/system-services/org.deepin.dde.Power1.service mkdir -pv ${DESTDIR}${PREFIX}/share/polkit-1/actions cp misc/polkit-action/*.policy ${DESTDIR}${PREFIX}/share/polkit-1/actions/ + rm -f ${DESTDIR}${PREFIX}/share/polkit-1/actions/org.deepin.dde.power.policy mkdir -pv ${DESTDIR}${PREFIX}/share/polkit-1/rules.d/ cp misc/polkit-rules/*.rules ${DESTDIR}${PREFIX}/share/polkit-1/rules.d/ @@ -227,6 +228,7 @@ install: build install-dde-data install-icons mkdir -pv ${DESTDIR}${PREFIX}/share/dsg/configs/org.deepin.dde.daemon/ cp -r misc/dsg-configs/*.json ${DESTDIR}${PREFIX}/share/dsg/configs/org.deepin.dde.daemon/ + rm -f ${DESTDIR}${PREFIX}/share/dsg/configs/org.deepin.dde.daemon/org.deepin.dde.daemon.power.json mkdir -pv ${DESTDIR}${PREFIX}/share/dsg/configs/org.deepin.dde.lightdm-deepin-greeter cp -r misc/dsg-configs/org.deepin.dde.lightdm-deepin-greeter/*.json ${DESTDIR}${PREFIX}/share/dsg/configs/org.deepin.dde.lightdm-deepin-greeter/ diff --git a/bin/dde-session-daemon/daemon.go b/bin/dde-session-daemon/daemon.go index bd5b043b5..57a7b4b74 100644 --- a/bin/dde-session-daemon/daemon.go +++ b/bin/dde-session-daemon/daemon.go @@ -186,7 +186,6 @@ func (s *SessionDaemon) initModules() { "audio", "screensaver", "sessionwatcher", - "power", // need screensaver and sessionwatcher "service-trigger", "clipboard", "inputdevices", diff --git a/bin/dde-session-daemon/main.go b/bin/dde-session-daemon/main.go index bd42a0156..018daf9ea 100755 --- a/bin/dde-session-daemon/main.go +++ b/bin/dde-session-daemon/main.go @@ -41,7 +41,7 @@ var logger = log.NewLogger("daemon/dde-session-daemon") var hasDDECookie bool var hasTreeLand bool -var treeLandNotAllowModules = []string{"x-event-monitor", "screensaver", "display", "xsettings", "power"} +var treeLandNotAllowModules = []string{"x-event-monitor", "screensaver", "display", "xsettings"} func isInShutdown() bool { bus, err := dbus.SystemBus() diff --git a/bin/dde-session-daemon/module.go b/bin/dde-session-daemon/module.go index 0be7b67a6..0628fd71a 100644 --- a/bin/dde-session-daemon/module.go +++ b/bin/dde-session-daemon/module.go @@ -29,7 +29,6 @@ import ( _ "github.com/linuxdeepin/dde-daemon/screensaver1" _ "github.com/linuxdeepin/dde-daemon/service_trigger" _ "github.com/linuxdeepin/dde-daemon/session/eventlog" - _ "github.com/linuxdeepin/dde-daemon/session/power1" _ "github.com/linuxdeepin/dde-daemon/sessionwatcher1" _ "github.com/linuxdeepin/dde-daemon/systeminfo1" _ "github.com/linuxdeepin/dde-daemon/timedate1" diff --git a/bin/dde-system-daemon/exported_methods_auto.go b/bin/dde-system-daemon/exported_methods_auto.go index fad8fe7cd..86a3db4e5 100644 --- a/bin/dde-system-daemon/exported_methods_auto.go +++ b/bin/dde-system-daemon/exported_methods_auto.go @@ -76,15 +76,5 @@ func (v *Daemon) GetExportedMethods() dbusutil.ExportedMethods { Fn: v.SetAllowCaller, InArgs: []string{"uniqueName"}, }, - { - Name: "SetIdleState", - Fn: v.SetIdleState, - InArgs: []string{"state"}, - }, - { - Name: "SetScreenState", - Fn: v.SetScreenState, - InArgs: []string{"state"}, - }, } } diff --git a/bin/dde-system-daemon/main.go b/bin/dde-system-daemon/main.go index fb44257e3..b0a7792a6 100644 --- a/bin/dde-system-daemon/main.go +++ b/bin/dde-system-daemon/main.go @@ -6,7 +6,6 @@ package main import ( "os" - "sync" configManager "github.com/linuxdeepin/go-dbus-factory/org.desktopspec.ConfigManager" @@ -23,7 +22,6 @@ import ( _ "github.com/linuxdeepin/dde-daemon/system/inputdevices1" _ "github.com/linuxdeepin/dde-daemon/system/keyevent1" _ "github.com/linuxdeepin/dde-daemon/system/lang" - _ "github.com/linuxdeepin/dde-daemon/system/power1" _ "github.com/linuxdeepin/dde-daemon/system/resource_ctl" _ "github.com/linuxdeepin/dde-daemon/system/scheduler" _ "github.com/linuxdeepin/dde-daemon/system/swapsched1" @@ -35,7 +33,6 @@ import ( "github.com/linuxdeepin/dde-daemon/loader" "github.com/linuxdeepin/dde-daemon/securityloader" login1 "github.com/linuxdeepin/go-dbus-factory/system/org.freedesktop.login1" - glib "github.com/linuxdeepin/go-gir/glib-2.0" "github.com/linuxdeepin/go-lib/dbusutil" . "github.com/linuxdeepin/go-lib/gettext" "github.com/linuxdeepin/go-lib/log" @@ -44,16 +41,13 @@ import ( //go:generate dbusutil-gen em -type Daemon type Daemon struct { - loginManager login1.Manager - systemSigLoop *dbusutil.SignalLoop - service *dbusutil.Service - systemd systemd1.Manager - dsSystem configManager.Manager - allowCallers *securityloader.AllowCallerRegistry - idleStateMu sync.Mutex - idleStatePath string - idleScreenStatePath string - signals *struct { // nolint + loginManager login1.Manager + systemSigLoop *dbusutil.SignalLoop + service *dbusutil.Service + systemd systemd1.Manager + dsSystem configManager.Manager + allowCallers *securityloader.AllowCallerRegistry + signals *struct { // nolint HandleForSleep struct { start bool } @@ -120,15 +114,12 @@ func main() { logger.SetRestartCommand("/usr/lib/deepin-daemon/dde-system-daemon") _daemon = &Daemon{ - loginManager: login1.NewManager(service.Conn()), - service: service, - systemSigLoop: dbusutil.NewSignalLoop(service.Conn(), 10), - systemd: systemd1.NewManager(service.Conn()), - allowCallers: allowCallers, - idleStatePath: IdleFile, - idleScreenStatePath: IdleScreenFile, + loginManager: login1.NewManager(service.Conn()), + service: service, + systemSigLoop: dbusutil.NewSignalLoop(service.Conn(), 10), + systemd: systemd1.NewManager(service.Conn()), + allowCallers: allowCallers, } - _daemon.getDsgValue() _daemon.service = service _daemon.initSystemDaemonDConfig() err = service.Export(dbusPath, _daemon) @@ -146,8 +137,6 @@ func main() { loader.StartAll() defer loader.StopAll() - // NOTE: system/power module requires glib loop - go glib.StartLoop() _daemon.systemSigLoop.Start() err = _daemon.forwardPrepareForSleepSignal(service) if err != nil { diff --git a/bin/dde-system-daemon/power.go b/bin/dde-system-daemon/power.go index a995d6159..c88b03fb4 100644 --- a/bin/dde-system-daemon/power.go +++ b/bin/dde-system-daemon/power.go @@ -5,88 +5,13 @@ package main import ( - "errors" - "fmt" - "os" "os/exec" - "strconv" - "strings" - "syscall" "github.com/godbus/dbus/v5" - "github.com/linuxdeepin/dde-daemon/loader" "github.com/linuxdeepin/dde-daemon/securityloader" - configManager "github.com/linuxdeepin/go-dbus-factory/org.desktopspec.ConfigManager" - "github.com/linuxdeepin/go-lib/dbusutil" - "github.com/linuxdeepin/go-lib/utils" -) - -const ( - IdleFile = "/sys/devices/system/loongarch/relax_state" - IdleScreenFile = "/sys/devices/system/loongarch/idle_state" -) - -const ( - dsettingsPowerName = "org.deepin.dde.daemon.power" - dsettingsIdleStatePath = "idleStatePath" - dsettingsIdleScreenStatePath = "idleScreenStatePath" ) -func isStrInList(item string, items []string) bool { - for _, v := range items { - if item == v { - return true - } - } - return false -} - -func (d *Daemon) getDsgValue() { - ds := configManager.NewConfigManager(d.systemSigLoop.Conn()) - - powerPath, err := ds.AcquireManager(0, dsettingsSystemDaemonID, dsettingsPowerName, "") - if err != nil { - logger.Warning(err) - return - } - - dsPower, err := configManager.NewManager(d.systemSigLoop.Conn(), powerPath) - if err != nil { - logger.Warning(err) - return - } - - keyList, err := dsPower.KeyList().Get(0) - if err != nil { - logger.Warning(err) - } - - if isStrInList(dsettingsIdleStatePath, keyList) { - v, err := dsPower.Value(0, dsettingsIdleStatePath) - if err != nil { - logger.Warning(err) - } else { - if dsgIdleStatePath, ok := v.Value().(string); ok { - d.idleStatePath = dsgIdleStatePath - logger.Info("idleStatePath : ", d.idleStatePath) - } - } - } - - if isStrInList(dsettingsIdleScreenStatePath, keyList) { - v, err := dsPower.Value(0, dsettingsIdleScreenStatePath) - if err != nil { - logger.Warning(err) - } else { - if dsgIdleScreenStatePath, ok := v.Value().(string); ok { - d.idleScreenStatePath = dsgIdleScreenStatePath - logger.Info("idleScreenStatePath : ", d.idleScreenStatePath) - } - } - } -} - // TODO: 临时方案,hwe一些机型内核wifi有问题,需要停止wifip2p扫描,待内核修改后去掉 func stopNetworkDisaplay() { err := exec.Command("killall", "deepin-network-display-daemon").Run() @@ -117,131 +42,6 @@ func (d *Daemon) forwardPrepareForSleepSignal(service *dbusutil.Service) error { return nil } -type shortIdleController interface { - ShortIdleState() (bool, error) - SetShortIdleState(bool) error -} - -func getShortIdleController() (shortIdleController, error) { - module := loader.GetModule("power") - if module == nil { - return nil, errors.New("power module is not registered") - } - if !module.IsEnable() { - return nil, errors.New("power module is not enabled") - } - controller, ok := module.(shortIdleController) - if !ok { - return nil, errors.New("power module does not support short idle control") - } - return controller, nil -} - -func systemPowerSetShortIdleState(controller shortIdleController, state bool) error { - logger.Info("systemPowerSetShortIdleState : ", state) - if err := controller.SetShortIdleState(state); err != nil { - return fmt.Errorf("failed to set short idle mode: %w", err) - } - return nil -} - -// 1.设置 system/power 模块的短 idle 状态 -// 2.写file内核文件 -func (d *Daemon) setState(file string, state bool) error { - if file != d.idleStatePath { - return d.writeStateFile(file, state) - } - - controller, err := getShortIdleController() - if err != nil { - return fmt.Errorf("failed to get short idle controller: %w", err) - } - return d.setStateWithController(controller, file, state) -} - -func (d *Daemon) setStateWithController(controller shortIdleController, file string, state bool) error { - d.idleStateMu.Lock() - defer d.idleStateMu.Unlock() - - shortIdleState, err := controller.ShortIdleState() - if err != nil { - return fmt.Errorf("failed to get short idle state: %w", err) - } - logger.Infof("##### setState shortIdleState : %v, state : %v", shortIdleState, state) - if shortIdleState == state { - logger.Info("shortIdleState is same with state : ", state) - return d.writeStateFile(file, state) - } - // 设置 system/power 模块的短 idle 状态 - if err := systemPowerSetShortIdleState(controller, state); err != nil { - return err - } - return d.writeStateFile(file, state) -} - -func (d *Daemon) writeStateFile(file string, state bool) error { - // 写file内核文件 - if !utils.IsFileExist(file) { - err := fmt.Errorf("%s not found", file) - logger.Warning(err) - return err - } - - // 读取file文件内容 - content, err := os.ReadFile(file) - if err != nil { - logger.Errorf("Failed to read file %s: %v", file, err) - return err - } - contentStr := strings.TrimSpace(string(content)) - - // 如果不一致,将state的值写入file - // 将true转换为1,false转换为0 - newValue := 0 - if state { - newValue = 1 - } - logger.Infof("Current content=%s, will set %v", contentStr, newValue) - // 将值写入文件 - newContent := strconv.Itoa(newValue) - err = os.WriteFile(file, []byte(newContent), 0644) - if err != nil { - logger.Errorf("Failed to write file %s: %v", file, err) - return err - } - syscall.Sync() - logger.Infof("Successfully updated %s with value: %d", file, newValue) - return nil -} - func (d *Daemon) SetAllowCaller(sender dbus.Sender, uniqueName string) *dbus.Error { return dbusutil.ToError(d.allowCallers.AddCaller(securityloader.DaemonScope, sender, uniqueName)) } - -func (d *Daemon) authorize(sender dbus.Sender, actionID string) error { - return securityloader.AuthorizeWithPolkit( - d.allowCallers, - securityloader.DaemonScope, - sender, - d.service.Conn(), - actionID, - ) -} - -func (d *Daemon) SetIdleState(sender dbus.Sender, state bool) *dbus.Error { - if err := d.authorize(sender, "org.deepin.dde.daemon.set-idle-state"); err != nil { - logger.Warningf("SetIdleState authorization failed: %q", err.Error()) - return dbusutil.ToError(err) - } - logger.Infof("SetIdleState %s try set state: %v", d.idleStatePath, state) - return dbusutil.ToError(d.setState(d.idleStatePath, state)) -} - -func (d *Daemon) SetScreenState(sender dbus.Sender, state bool) *dbus.Error { - if err := d.authorize(sender, "org.deepin.dde.daemon.set-screen-state"); err != nil { - logger.Warningf("SetScreenState authorization failed: %q", err.Error()) - return dbusutil.ToError(err) - } - logger.Infof("SetScreenState %s try set state: %v", d.idleScreenStatePath, state) - return dbusutil.ToError(d.setState(d.idleScreenStatePath, state)) -} \ No newline at end of file diff --git a/bin/dde-system-daemon/power_test.go b/bin/dde-system-daemon/power_test.go deleted file mode 100644 index 6e3f86f39..000000000 --- a/bin/dde-system-daemon/power_test.go +++ /dev/null @@ -1,237 +0,0 @@ -// SPDX-FileCopyrightText: 2026 UnionTech Software Technology Co., Ltd. -// -// SPDX-License-Identifier: GPL-3.0-or-later - -package main - -import ( - "errors" - "os" - "path/filepath" - "sync" - "testing" - "time" -) - -type fakeShortIdleController struct { - state bool - getErr error - setErr error - setCalls int -} - -func (c *fakeShortIdleController) ShortIdleState() (bool, error) { - return c.state, c.getErr -} - -func (c *fakeShortIdleController) SetShortIdleState(state bool) error { - c.setCalls++ - if c.setErr != nil { - return c.setErr - } - c.state = state - return nil -} - -type blockingShortIdleController struct { - mu sync.Mutex - state bool - getCalls int - firstSet sync.Once - firstSetStarted chan struct{} - releaseFirstSet chan struct{} - secondGetCalled chan struct{} -} - -func (c *blockingShortIdleController) ShortIdleState() (bool, error) { - c.mu.Lock() - defer c.mu.Unlock() - - c.getCalls++ - if c.getCalls == 2 { - close(c.secondGetCalled) - } - return c.state, nil -} - -func (c *blockingShortIdleController) SetShortIdleState(state bool) error { - c.mu.Lock() - c.state = state - c.mu.Unlock() - - c.firstSet.Do(func() { - close(c.firstSetStarted) - <-c.releaseFirstSet - }) - return nil -} - -func (c *blockingShortIdleController) currentState() bool { - c.mu.Lock() - defer c.mu.Unlock() - return c.state -} - -func TestSetStateWithControllerGetErrorDoesNotWrite(t *testing.T) { - stateFile := filepath.Join(t.TempDir(), "relax_state") - if err := os.WriteFile(stateFile, []byte("0"), 0644); err != nil { - t.Fatal(err) - } - - controller := &fakeShortIdleController{getErr: errors.New("get failed")} - d := &Daemon{idleStatePath: stateFile} - if err := d.setStateWithController(controller, stateFile, true); err == nil { - t.Fatal("expected get state error") - } - - content, err := os.ReadFile(stateFile) - if err != nil { - t.Fatal(err) - } - if string(content) != "0" { - t.Fatalf("state file changed after getter failure: %q", content) - } - if controller.setCalls != 0 { - t.Fatalf("setter called after getter failure: %d", controller.setCalls) - } -} - -func TestSetStateWithControllerSetErrorDoesNotWrite(t *testing.T) { - stateFile := filepath.Join(t.TempDir(), "relax_state") - if err := os.WriteFile(stateFile, []byte("0"), 0644); err != nil { - t.Fatal(err) - } - - controller := &fakeShortIdleController{setErr: errors.New("set failed")} - d := &Daemon{idleStatePath: stateFile} - if err := d.setStateWithController(controller, stateFile, true); err == nil { - t.Fatal("expected set state error") - } - - content, err := os.ReadFile(stateFile) - if err != nil { - t.Fatal(err) - } - if string(content) != "0" { - t.Fatalf("state file changed after setter failure: %q", content) - } - if controller.setCalls != 1 { - t.Fatalf("unexpected setter call count: %d", controller.setCalls) - } -} - -func TestSetScreenStateWritesWithoutController(t *testing.T) { - screenStateFile := filepath.Join(t.TempDir(), "idle_state") - if err := os.WriteFile(screenStateFile, []byte("1"), 0644); err != nil { - t.Fatal(err) - } - - d := &Daemon{ - idleStatePath: filepath.Join(t.TempDir(), "relax_state"), - idleScreenStatePath: screenStateFile, - } - if err := d.setState(screenStateFile, false); err != nil { - t.Fatalf("set screen state: %v", err) - } - - content, err := os.ReadFile(screenStateFile) - if err != nil { - t.Fatal(err) - } - if string(content) != "0" { - t.Fatalf("screen state file = %q, want %q", content, "0") - } -} - -func TestSetStateWithControllerRetryRepairsFile(t *testing.T) { - stateFile := filepath.Join(t.TempDir(), "relax_state") - controller := new(fakeShortIdleController) - d := &Daemon{idleStatePath: stateFile} - - if err := d.setStateWithController(controller, stateFile, true); err == nil { - t.Fatal("expected first write to fail") - } - if !controller.state { - t.Fatal("controller state was not updated before the write failure") - } - - if err := os.WriteFile(stateFile, []byte("0"), 0644); err != nil { - t.Fatal(err) - } - if err := d.setStateWithController(controller, stateFile, true); err != nil { - t.Fatalf("retry state file write: %v", err) - } - - content, err := os.ReadFile(stateFile) - if err != nil { - t.Fatal(err) - } - if string(content) != "1" { - t.Fatalf("state file = %q, want %q", content, "1") - } - if controller.setCalls != 1 { - t.Fatalf("unexpected setter call count: %d", controller.setCalls) - } -} - -func TestSetStateWithControllerSerializesTransitions(t *testing.T) { - stateFile := filepath.Join(t.TempDir(), "relax_state") - if err := os.WriteFile(stateFile, []byte("0"), 0644); err != nil { - t.Fatal(err) - } - - controller := &blockingShortIdleController{ - firstSetStarted: make(chan struct{}), - releaseFirstSet: make(chan struct{}), - secondGetCalled: make(chan struct{}), - } - d := &Daemon{idleStatePath: stateFile} - - firstErr := make(chan error, 1) - go func() { - firstErr <- d.setStateWithController(controller, stateFile, true) - }() - - select { - case <-controller.firstSetStarted: - case <-time.After(time.Second): - t.Fatal("first transition did not reach the setter") - } - - secondErr := make(chan error, 1) - secondStarted := make(chan struct{}) - go func() { - close(secondStarted) - secondErr <- d.setStateWithController(controller, stateFile, false) - }() - <-secondStarted - - serialized := true - select { - case <-controller.secondGetCalled: - serialized = false - case <-time.After(100 * time.Millisecond): - } - - close(controller.releaseFirstSet) - if err := <-firstErr; err != nil { - t.Fatalf("first transition: %v", err) - } - if err := <-secondErr; err != nil { - t.Fatalf("second transition: %v", err) - } - if !serialized { - t.Fatal("second transition entered before the first transition completed") - } - - content, err := os.ReadFile(stateFile) - if err != nil { - t.Fatal(err) - } - if string(content) != "0" { - t.Fatalf("state file = %q, want %q", content, "0") - } - if controller.currentState() { - t.Fatal("controller state and state file are inconsistent") - } -} \ No newline at end of file diff --git a/debian/control b/debian/control index ba6db003e..0a6688efa 100644 --- a/debian/control +++ b/debian/control @@ -85,7 +85,7 @@ Depends: x11-utils, xkb-data, dde-dconfig-daemon, - dde-services (>> 1.0.39), + dde-services (>> 1.0.41), ${dist:Depends}, ${misc:Depends}, ${shlibs:Depends}, diff --git a/keybinding1/utils.go b/keybinding1/utils.go index 2bf9c7c30..93eaacab8 100644 --- a/keybinding1/utils.go +++ b/keybinding1/utils.go @@ -18,9 +18,9 @@ import ( login1 "github.com/linuxdeepin/go-dbus-factory/system/org.freedesktop.login1" dbus "github.com/godbus/dbus/v5" + "github.com/linuxdeepin/dde-daemon/common/fileutil" "github.com/linuxdeepin/dde-daemon/keybinding1/constants" "github.com/linuxdeepin/dde-daemon/keybinding1/util" - "github.com/linuxdeepin/dde-daemon/common/fileutil" wm "github.com/linuxdeepin/go-dbus-factory/session/com.deepin.wm" gio "github.com/linuxdeepin/go-gir/gio-2.0" @@ -458,14 +458,14 @@ func callSetScreenState(state bool) { return } - logger.Infof("callSetScreenState: calling SetScreenState with state=%v", state) - err = systemConn.Object("org.deepin.dde.Daemon1", "/org/deepin/dde/Daemon1").Call("org.deepin.dde.Daemon1.SetScreenState", 0, dbus.MakeVariant(state)).Err + logger.Infof("callSetScreenState: calling Power1.SetScreenState with state=%v", state) + err = systemConn.Object("org.deepin.dde.Power1", "/org/deepin/dde/Power1").Call("org.deepin.dde.Power1.SetScreenState", 0, dbus.MakeVariant(state)).Err if err != nil { logger.Warning(err) return } - logger.Infof("callSetScreenState: SetScreenState called successfully with state=%v", state) + logger.Infof("callSetScreenState: Power1.SetScreenState called successfully with state=%v", state) } func doPrepareSuspend() { diff --git a/misc/polkit-action/org.deepin.dde.hardware-control.policy.in b/misc/polkit-action/org.deepin.dde.hardware-control.policy.in index 21cd4e5b3..362f61776 100644 --- a/misc/polkit-action/org.deepin.dde.hardware-control.policy.in +++ b/misc/polkit-action/org.deepin.dde.hardware-control.policy.in @@ -5,27 +5,6 @@ - - - Set idle state - Authentication is required to set idle state - - no - no - auth_admin_keep - - - - - Set screen state - Authentication is required to set screen state - - no - no - auth_admin_keep - - - Enable or disable touchpad Authentication is required to enable or disable touchpad diff --git a/session/power1/constant.go b/session/power1/constant.go deleted file mode 100644 index 686d258c0..000000000 --- a/session/power1/constant.go +++ /dev/null @@ -1,84 +0,0 @@ -// SPDX-FileCopyrightText: 2018 - 2026 UnionTech Software Technology Co., Ltd. -// -// SPDX-License-Identifier: GPL-3.0-or-later - -package power - -// nolint -const ( - // cmd - cmdDDELowPower = "/usr/lib/deepin-daemon/dde-lowpower" - - batteryDisplay = "Display" -) - -// dconfig keys -const ( - dsettingLinePowerScreensaverDelay = "linePowerScreensaverDelay" - dsettingBatteryScreensaverDelay = "batteryScreensaverDelay" - dsettingPowerSavingModeBrightnessDropPercent = "powerSavingModeBrightnessDropPercent" - dsettingBatteryScreenBlackDelay = "batteryScreenBlackDelay" - dsettingBatterySleepDelay = "batterySleepDelay" - dsettingLinePowerScreenBlackDelay = "linePowerScreenBlackDelay" - dsettingLinePowerSleepDelay = "linePowerSleepDelay" - dsettingLinePowerLockDelay = "linePowerLockDelay" - dsettingBatteryLockDelay = "batteryLockDelay" - dsettingAdjustBrightnessEnabled = "adjustBrightnessEnabled" - dsettingScreenBlackLock = "screenBlackLock" - dsettingSleepLock = "sleepLock" - dsettingLidClosedSleep = "lidClosedSleep" - dsettingBatteryLidClosedSleep = "batteryLidClosedSleep" - dsettingPowerButtonPressedExec = "powerButtonPressedExec" - dsettingFullscreenWorkaroundAppList = "fullscreenWorkaroundAppList" - dsettingUsePercentageForPolicy = "usePercentageForPolicy" - dsettingPowerModuleInitialized = "powerModuleInitialized" - dsettingLowPowerNotifyThreshold = "lowPowerNotifyThreshold" - dsettingLowPowerAction = "lowPowerAction" - dsettingPercentageAction = "percentageAction" - dsettingTimeToEmptyLow = "timeToEmptyLow" - dsettingTimeToEmptyDanger = "timeToEmptyDanger" - dsettingTimeToEmptyCritical = "timeToEmptyCritical" - dsettingTimeToEmptyAction = "timeToEmptyAction" - dsettingLinePowerLidClosedAction = "linePowerLidClosedAction" - dsettingLinePowerPressPowerButton = "linePowerPressPowerButton" - dsettingBatteryLidClosedAction = "batteryLidClosedAction" - dsettingBatteryPressPowerButton = "batteryPressPowerButton" - dsettingLowPowerNotifyEnable = "lowPowerNotifyEnable" - dsettingSaveBrightnessWhilePsm = "saveBrightnessWhilePsm" - dsettingLowPowerPercentInUpdatingNotify = "lowPowerPercentInUpdatingNotify" - dsettingHighPerformanceEnabled = "highPerformanceEnabled" - dsettingsPowerSavingModeEnabled = "powerSavingModeEnabled" - dsettingScheduledShutdownState = "scheduledShutdownState" - dsettingShutdownTime = "shutdownTime" - dsettingShutdownRepetition = "shutdownRepetition" - dsettingCustomShutdownWeekDays = "customShutdownWeekDays" - dsettingShutdownCountdown = "shutdownCountdown" - dsettingNextShutdownTime = "nextShutdownTime" - dsettingsSystemApplications = "systemApplications" - dsettingsSystemServices = "systemServices" - dsettingsShortIdleState = "shortIdleState" - dsettingsShortIdleEnable = "shortIdleEnable" - dsettingsShortIdleBlacklistApplications = "shortIdleBlacklistApplications" - dsettingsLinePowerShortIdleDelay = "linePowerShortIdleDelay" - dsettingsBatteryShortIdleDelay = "batteryShortIdleDelay" -) - -const ( - DSettingsAppID = "org.deepin.dde.daemon" - DSettingsDisplayName = "org.deepin.Display" - DSettingsAutoChangeWm = "auto-change-deepin-wm" -) - -const ( - powerActionShutdown int32 = iota - powerActionSuspend - powerActionHibernate - powerActionTurnOffScreen - powerActionShowShutdownInterface - powerActionDoNothing -) - -const ( - lowPowerActionSuspend int32 = iota - lowPowerActionHibernate -) diff --git a/session/power1/count_ticker.go b/session/power1/count_ticker.go deleted file mode 100644 index 0eff5f7af..000000000 --- a/session/power1/count_ticker.go +++ /dev/null @@ -1,62 +0,0 @@ -// SPDX-FileCopyrightText: 2018 - 2022 UnionTech Software Technology Co., Ltd. -// -// SPDX-License-Identifier: GPL-3.0-or-later - -package power - -import ( - "time" -) - -type countTicker struct { - action func(int) - interval time.Duration - count int - ticker *time.Ticker - exit chan struct{} -} - -func newCountTicker(interval time.Duration, action func(int)) *countTicker { - t := &countTicker{ - interval: interval, - action: action, - } - t.Reset() - return t -} - -func (t *countTicker) Reset() { - t.ticker = time.NewTicker(t.interval) - t.count = 0 - t.action(0) - t.exit = make(chan struct{}) - go func() { - for { - select { - case _, ok := <-t.ticker.C: - if !ok { - logger.Error("Invalid ticker event") - return - } - - t.count++ - logger.Debug("tick", t.count) - t.action(t.count) - case <-t.exit: - t.exit = nil - return - } - } - }() -} - -func (t *countTicker) Stop() { - if t.ticker != nil { - logger.Debug("Stop") - t.ticker.Stop() - } - if t.exit != nil { - logger.Debug("exit") - close(t.exit) - } -} diff --git a/session/power1/daemon.go b/session/power1/daemon.go deleted file mode 100644 index 10bccfe39..000000000 --- a/session/power1/daemon.go +++ /dev/null @@ -1,89 +0,0 @@ -// SPDX-FileCopyrightText: 2018 - 2022 UnionTech Software Technology Co., Ltd. -// -// SPDX-License-Identifier: GPL-3.0-or-later - -package power - -import ( - "os" - - "github.com/linuxdeepin/dde-daemon/loader" - "github.com/linuxdeepin/go-lib/log" -) - -var logger = log.NewLogger("daemon/session/power") - -func init() { - loader.Register(NewDaemon(logger)) -} - -type Daemon struct { - *loader.ModuleBase - manager *Manager -} - -func NewDaemon(logger *log.Logger) *Daemon { - daemon := new(Daemon) - daemon.ModuleBase = loader.NewModuleBase("power", daemon, logger) - return daemon -} - -func (d *Daemon) GetDependencies() []string { - // TODO: Idle在treeland暂时有问题 - if os.Getenv("XDG_SESSION_TYPE") == "wayland" { - return []string{"sessionwatcher"} - } - return []string{"screensaver", "sessionwatcher"} -} - -func (d *Daemon) Start() error { - service := loader.GetService() - var err error - d.manager, err = newManager(service) - if err != nil { - return err - } - - err = service.Export(dbusPath, d.manager, - d.manager.warnLevelConfig, d.manager.syncConfig) - if err != nil { - return err - } - - err = service.RequestName(dbusServiceName) - if err != nil { - return err - } - - err = d.manager.syncConfig.Register() - if err != nil { - logger.Warning("failed to register for deepin sync:", err) - } - - go d.manager.init() - _manager = d.manager - return nil -} - -func (d *Daemon) Stop() error { - if d.manager == nil { - return nil - } - service := loader.GetService() - err := service.ReleaseName(dbusServiceName) - if err != nil { - logger.Warning(err) - } - err = service.StopExport(d.manager) - if err != nil { - logger.Warning(err) - } - err = service.StopExport(d.manager.syncConfig) - if err != nil { - logger.Warning(err) - } - - d.manager.destroy() - d.manager = nil - return nil -} diff --git a/session/power1/delayed_task.go b/session/power1/delayed_task.go deleted file mode 100644 index d8a6350ae..000000000 --- a/session/power1/delayed_task.go +++ /dev/null @@ -1,87 +0,0 @@ -// SPDX-FileCopyrightText: 2018 - 2022 UnionTech Software Technology Co., Ltd. -// -// SPDX-License-Identifier: GPL-3.0-or-later - -package power - -import ( - "sync" - "time" -) - -type delayedTaskState uint - -const ( - delayedTaskStateReady delayedTaskState = iota - delayedTaskStateRunning - delayedTaskStateDone -) - -type delayedTask struct { - state delayedTaskState - mu sync.Mutex - cancelable bool - timer *time.Timer - name string -} - -func newDelayedTask(name string, delay time.Duration, fn func()) *delayedTask { - t := &delayedTask{ - state: delayedTaskStateReady, - cancelable: true, - name: name, - } - t.timer = time.AfterFunc(delay, func() { - t.mu.Lock() - t.cancelable = false - t.state = delayedTaskStateRunning - t.mu.Unlock() - - fn() - - t.mu.Lock() - t.state = delayedTaskStateDone - t.mu.Unlock() - }) - return t -} - -func (t *delayedTask) Cancel() { - t.mu.Lock() - if t.cancelable { - t.timer.Stop() - t.state = delayedTaskStateDone - logger.Debugf("delayedTask %s cancelled", t.name) - } - t.mu.Unlock() -} - -type delayedTasks []*delayedTask - -func (tasks delayedTasks) Wait(delay time.Duration, countMax int) { - count := 0 - for { - allDone := true - for _, task := range tasks { - task.mu.Lock() - state := task.state - task.mu.Unlock() - - if state != delayedTaskStateDone { - allDone = false - break - } - } - if allDone || count >= countMax { - break - } - time.Sleep(delay) - count++ - } -} - -func (tasks delayedTasks) CancelAll() { - for _, task := range tasks { - task.Cancel() - } -} diff --git a/session/power1/exported_methods_auto.go b/session/power1/exported_methods_auto.go deleted file mode 100644 index 3aabaa23d..000000000 --- a/session/power1/exported_methods_auto.go +++ /dev/null @@ -1,29 +0,0 @@ -// Code generated by "dbusutil-gen em -type Manager,WarnLevelConfigManager"; DO NOT EDIT. - -package power - -import ( - "github.com/linuxdeepin/go-lib/dbusutil" -) - -func (v *Manager) GetExportedMethods() dbusutil.ExportedMethods { - return dbusutil.ExportedMethods{ - { - Name: "Reset", - Fn: v.Reset, - }, - { - Name: "SetPrepareSuspend", - Fn: v.SetPrepareSuspend, - InArgs: []string{"suspendState"}, - }, - } -} -func (v *WarnLevelConfigManager) GetExportedMethods() dbusutil.ExportedMethods { - return dbusutil.ExportedMethods{ - { - Name: "Reset", - Fn: v.Reset, - }, - } -} diff --git a/session/power1/helper.go b/session/power1/helper.go deleted file mode 100644 index 0f48233e0..000000000 --- a/session/power1/helper.go +++ /dev/null @@ -1,107 +0,0 @@ -// SPDX-FileCopyrightText: 2018-2026 UnionTech Software Technology Co., Ltd. -// -// SPDX-License-Identifier: GPL-3.0-or-later - -package power - -import ( - "github.com/godbus/dbus/v5" - notifications "github.com/linuxdeepin/go-dbus-factory/session/org.freedesktop.notifications" - "github.com/linuxdeepin/go-lib/dbusutil/proxy" - "os" - - // system bus - shutdownfront "github.com/linuxdeepin/go-dbus-factory/session/org.deepin.dde.shutdownfront1" - daemon "github.com/linuxdeepin/go-dbus-factory/system/org.deepin.dde.daemon1" - libpower "github.com/linuxdeepin/go-dbus-factory/system/org.deepin.dde.power1" - ofdbus "github.com/linuxdeepin/go-dbus-factory/system/org.freedesktop.dbus" - login1 "github.com/linuxdeepin/go-dbus-factory/system/org.freedesktop.login1" - - // session bus - display "github.com/linuxdeepin/go-dbus-factory/session/org.deepin.dde.display1" - sessionmanager "github.com/linuxdeepin/go-dbus-factory/session/org.deepin.dde.sessionmanager1" - sessionwatcher "github.com/linuxdeepin/go-dbus-factory/session/org.deepin.dde.sessionwatcher1" - screensaver "github.com/linuxdeepin/go-dbus-factory/session/org.freedesktop.screensaver" - "github.com/linuxdeepin/go-lib/dbusutil" - x "github.com/linuxdeepin/go-x11-client" -) - - -type Helper struct { - Notifications notifications.Notifications - - Power libpower.Power // sig - LoginManager login1.Manager // sig - SysDBusDaemon ofdbus.DBus - Daemon daemon.Daemon - - SessionManager sessionmanager.SessionManager - SessionWatcher sessionwatcher.SessionWatcher - ShutdownFront shutdownfront.ShutdownFront - ScreenSaver screensaver.ScreenSaver // sig - Display display.Display - - xConn *x.Conn -} - -func newHelper(systemBus, sessionBus *dbus.Conn) (*Helper, error) { - h := &Helper{} - err := h.init(systemBus, sessionBus) - if err != nil { - return nil, err - } - return h, nil -} - -func (h *Helper) init(sysBus, sessionBus *dbus.Conn) error { - var err error - - h.Notifications = notifications.NewNotifications(sessionBus) - - h.Power = libpower.NewPower(sysBus) - h.LoginManager = login1.NewManager(sysBus) - h.SysDBusDaemon = ofdbus.NewDBus(sysBus) - h.Daemon = daemon.NewDaemon(sysBus) - h.SessionManager = sessionmanager.NewSessionManager(sessionBus) - h.ScreenSaver = screensaver.NewScreenSaver(sessionBus) - h.Display = display.NewDisplay(sessionBus) - h.SessionWatcher = sessionwatcher.NewSessionWatcher(sessionBus) - h.ShutdownFront = shutdownfront.NewShutdownFront(sessionBus) - - // init X conn - if os.Getenv("XDG_SESSION_TYPE") != "wayland" { - h.xConn, err = x.NewConn() - if err != nil { - return err - } - } - return nil -} - - -func (h *Helper) initSignalExt(systemSigLoop, sessionSigLoop *dbusutil.SignalLoop) { - // sys - h.SysDBusDaemon.InitSignalExt(systemSigLoop, true) - h.LoginManager.InitSignalExt(systemSigLoop, true) - h.Power.InitSignalExt(systemSigLoop, true) - h.Daemon.InitSignalExt(systemSigLoop, true) - // session - h.ScreenSaver.InitSignalExt(sessionSigLoop, true) - h.SessionWatcher.InitSignalExt(sessionSigLoop, true) - h.Display.InitSignalExt(sessionSigLoop, true) -} - -func (h *Helper) Destroy() { - h.SysDBusDaemon.RemoveHandler(proxy.RemoveAllHandlers) - h.LoginManager.RemoveHandler(proxy.RemoveAllHandlers) - h.Power.RemoveHandler(proxy.RemoveAllHandlers) - h.Daemon.RemoveHandler(proxy.RemoveAllHandlers) - - h.ScreenSaver.RemoveHandler(proxy.RemoveAllHandlers) - h.SessionWatcher.RemoveHandler(proxy.RemoveAllHandlers) - - if h.xConn != nil { - h.xConn.Close() - h.xConn = nil - } -} diff --git a/session/power1/lid_switch.go b/session/power1/lid_switch.go deleted file mode 100644 index ffb295895..000000000 --- a/session/power1/lid_switch.go +++ /dev/null @@ -1,188 +0,0 @@ -// SPDX-FileCopyrightText: 2018-2026 UnionTech Software Technology Co., Ltd. -// -// SPDX-License-Identifier: GPL-3.0-or-later - -package power - -import ( - "os/exec" - "strings" - "time" -) - -func init() { - submoduleList = append(submoduleList, newLidSwitchHandler) -} - -// nolint -const ( - lidSwitchStateUnknown = iota - lidSwitchStateOpen - lidSwitchStateClose -) - -type LidSwitchHandler struct { - manager *Manager - cmd *exec.Cmd - cookie chan struct{} -} - -func newLidSwitchHandler(m *Manager) (string, submodule, error) { - h := &LidSwitchHandler{ - manager: m, - } - return "LidSwitchHandler", h, nil -} - -func (h *LidSwitchHandler) Start() error { - power := h.manager.helper.Power - _, err := power.ConnectLidClosed(h.onLidClosed) - if err != nil { - return err - } - _, err = power.ConnectLidOpened(h.onLidOpened) - if err != nil { - return err - } - return nil -} - -func (h *LidSwitchHandler) onLidClosed() { - h.onLidDelayOperate(false) -} - -func (h *LidSwitchHandler) onLidOpened() { - h.onLidDelayOperate(true) -} - -func (h *LidSwitchHandler) onLidDelayOperate(state bool) { - if _manager != nil && !_manager.sessionActive { // session未激活状态不处理 - return - } - if h.cookie != nil { - h.cookie <- struct{}{} - close(h.cookie) - } - - h.cookie = make(chan struct{}, 1) - - go func() { - select { - case <-h.cookie: - break - // 1.5s是为了保证在关闭显示器时,其强制等待的1秒操作被完全执行,否则会带来闪屏问题 - case <-time.After(time.Millisecond * 1500): - h.doLidStateChanged(state) - break - } - }() -} - -func (h *LidSwitchHandler) doLidStateChanged(state bool) { - logger.Info("Lid open:", state) - - m := h.manager - m.setPrepareSuspend(suspendStateLidClose) - m.PropsMu.Lock() - m.lidSwitchState = lidSwitchStateClose - m.PropsMu.Unlock() - - // 合盖 - if !state { - var onBattery bool - onBattery = h.manager.OnBattery - var lidCloseAction int32 - if onBattery { - lidCloseAction = m.BatteryLidClosedAction // 获取合盖操作 - } else { - lidCloseAction = m.LinePowerLidClosedAction // 获取合盖操作 - } - switch lidCloseAction { - case powerActionShutdown: - m.doShutdown() - case powerActionSuspend: - if m.UseWayland { - m.doSuspend() - } else { - m.doSuspendByFront() - } - case powerActionHibernate: - if m.UseWayland { - m.doHibernate() - } else { - m.doHibernateByFront() - } - case powerActionTurnOffScreen: - m.doTurnOffScreen() - case powerActionDoNothing: - return - } - - if lidCloseAction != powerActionTurnOffScreen { - m.setDDEBlackScreenActive(true) - } - } else { // 开盖 - err := h.stopAskUser() - if err != nil { - logger.Warning("stopAskUser error:", err) - } - - // x11环境在待机唤醒后,会接收到screensaver的ConnectIdleOff信息将待机状态更新为suspendStateFinish状态 - // wayland环境下,并没有做这个处理,此处在开盖后手动更新状态为suspendStateFinish - if m.UseWayland { - m.setPrepareSuspend(suspendStateFinish) - } - - err = m.helper.ScreenSaver.SimulateUserActivity(0) - if err != nil { - logger.Warning(err) - } - - m.setDDEBlackScreenActive(false) - m.setDPMSModeOn() - } -} - -func (h *LidSwitchHandler) stopAskUser() error { - if h.cmd == nil { - return nil - } - - if h.cmd.ProcessState == nil { - // h.cmd is running - logger.Debug("stopAskUser: kill process") - err := h.cmd.Process.Kill() - if err != nil { - return err - } - } else { - logger.Debug("stopAskUser: cmd exited") - } - h.cmd = nil - return nil -} - -// copy from display module of project startdde -func isBuiltinOutput(name string) bool { - name = strings.ToLower(name) - switch { - case strings.Contains(name, "lvds"): - // Most drivers use an "LVDS" prefix - fallthrough - case strings.Contains(name, "lcd"): - // fglrx uses "LCD" in some versions - fallthrough - case strings.Contains(name, "edp"): - // eDP is for internal built-in panel connections - fallthrough - case strings.Contains(name, "dsi"): - return true - case name == "default": - // now sunway notebook has only one output named default - return true - } - return false -} - -func (h *LidSwitchHandler) Destroy() { -} diff --git a/session/power1/manager.go b/session/power1/manager.go deleted file mode 100644 index 26e208896..000000000 --- a/session/power1/manager.go +++ /dev/null @@ -1,1574 +0,0 @@ -// SPDX-FileCopyrightText: 2018 - 2026 UnionTech Software Technology Co., Ltd. -// -// SPDX-License-Identifier: GPL-3.0-or-later - -package power - -import ( - "encoding/json" - "errors" - "fmt" - - dutils "github.com/linuxdeepin/go-lib/utils" - - "os" - "sync" - "syscall" - "time" - - dbus "github.com/godbus/dbus/v5" - "github.com/linuxdeepin/dde-daemon/common/dsync" - "github.com/linuxdeepin/dde-daemon/session/common" - configManager "github.com/linuxdeepin/go-dbus-factory/org.desktopspec.ConfigManager" - calendar "github.com/linuxdeepin/go-dbus-factory/session/com.deepin.dataserver.Calendar" - wm "github.com/linuxdeepin/go-dbus-factory/session/com.deepin.wm" - display "github.com/linuxdeepin/go-dbus-factory/session/org.deepin.dde.display1" - sessionmanager "github.com/linuxdeepin/go-dbus-factory/session/org.deepin.dde.sessionmanager1" - shutdownfront "github.com/linuxdeepin/go-dbus-factory/session/org.deepin.dde.shutdownfront1" - sessiontimedate "github.com/linuxdeepin/go-dbus-factory/session/org.deepin.dde.timedate1" - ofdbus "github.com/linuxdeepin/go-dbus-factory/session/org.freedesktop.dbus" - notifications "github.com/linuxdeepin/go-dbus-factory/session/org.freedesktop.notifications" - systemPower "github.com/linuxdeepin/go-dbus-factory/system/org.deepin.dde.power1" - DisplayManager "github.com/linuxdeepin/go-dbus-factory/system/org.freedesktop.DisplayManager" - login1 "github.com/linuxdeepin/go-dbus-factory/system/org.freedesktop.login1" - timedate "github.com/linuxdeepin/go-dbus-factory/system/org.freedesktop.timedate1" - "github.com/linuxdeepin/go-lib/dbusutil" - "github.com/linuxdeepin/go-lib/gettext" -) - -//go:generate dbusutil-gen -type Manager manager.go -//go:generate dbusutil-gen em -type Manager,WarnLevelConfigManager - -const ( - Once int = iota - Everyday - Workdays - Custom -) - -type FestivalRootConfig struct { - Description string `json:"description"` - Id string `json:"id"` - List []HolidayDate `json:"list"` - Month byte `json:"month"` - NewDaemoname string `json:"name"` - Rest string `json:"rest"` -} - -type HolidayDate struct { - Date string `json:"date"` - Status byte `json:"status"` -} - -type Manager struct { - service *dbusutil.Service - sessionSigLoop *dbusutil.SignalLoop - systemSigLoop *dbusutil.SignalLoop - syncConfig *dsync.Config - helper *Helper - warnLevelCountTicker *countTicker - warnLevelConfig *WarnLevelConfigManager - submodules map[string]submodule - inhibitor *sleepInhibitor - inhibitFd dbus.UnixFD - systemPower systemPower.Power - display display.Display - calendar calendar.HuangLi - objLogin login1.Manager - ddeShutdown shutdownfront.ShutdownFront - displayManager DisplayManager.DisplayManager - - sessionManager sessionmanager.SessionManager - currentSessionPath dbus.ObjectPath - currentSession login1.Session - - // 定时关机 - ScheduledShutdownState bool `prop:"access:rw"` - ShutdownTime string `prop:"access:rw"` - ShutdownRepetition int `prop:"access:rw"` - // dbusutil-gen: equal=byteSliceEqual - CustomShutdownWeekDays []byte `prop:"access:rw"` - shutdownTimer *time.Timer - shutdownCountdown int - notifyId uint32 - notifyIdMu sync.Mutex - notify notifications.Notifications - - nextShutdownTime int64 // 下一次关机时间,只有关机配置、系统时间/时区等手动更改时,触发变更. 0则为无效日期 - shutdownStatus int - - sessionTimeDate sessiontimedate.Timedate - timeDate timedate.Timedate - - PropsMu sync.RWMutex - dsgMu sync.Mutex - - // 是否有盖子,一般笔记本电脑才有 - LidIsPresent bool - // 是否使用电池, 接通电源时为 false, 使用电池时为 true - OnBattery bool - // 是否使用Wayland - UseWayland bool - // 警告级别 - WarnLevel WarnLevel - - // 电池是否可用,是否存在 - - // dbusutil-gen: ignore - BatteryIsPresent map[string]bool - - // 电池电量百分比 - - // dbusutil-gen: ignore - BatteryPercentage map[string]float64 - - // 电池状态 - - // dbusutil-gen: ignore - BatteryState map[string]uint32 - - // 接通电源时,不做任何操作,到显示屏保的时间 - LinePowerScreensaverDelay int `prop:"access:rw"` - // 接通电源时,不做任何操作,到关闭屏幕的时间 - LinePowerScreenBlackDelay int `prop:"access:rw"` - // 接通电源时,不做任何操作,到睡眠的时间 - LinePowerSleepDelay int `prop:"access:rw"` - - // 使用电池时,不做任何操作,到显示屏保的时间 - BatteryScreensaverDelay int `prop:"access:rw"` - // 使用电池时,不做任何操作,到关闭屏幕的时间 - BatteryScreenBlackDelay int `prop:"access:rw"` - // 使用电池时,不做任何操作,到睡眠的时间 - BatterySleepDelay int `prop:"access:rw"` - - // 接通电源时,不做任何操作,到短idle的时间 - LinePowerShortIdleDelay int `prop:"access:rw"` - // 使用电池时,不做任何操作,到短idle的时间 - BatteryShortIdleDelay int `prop:"access:rw"` - - // 关闭屏幕前是否锁定 - ScreenBlackLock bool `prop:"access:rw"` - // 睡眠前是否锁定 - SleepLock bool `prop:"access:rw"` - - // 接通电源时,笔记本电脑盖上盖子 待机(默认选择)、睡眠、关闭显示器、无任何操作 - LinePowerLidClosedAction int32 `prop:"access:rw"` - - // 接通电源时,按下电源按钮 关机(默认选择)、待机、睡眠、关闭显示器、无任何操作 - LinePowerPressPowerBtnAction int32 `prop:"access:rw"` // keybinding中监听power按键事件,获取gsettings的值 - - // 使用电池时,笔记本电脑盖上盖子 待机(默认选择)、睡眠、关闭显示器、无任何操作 - BatteryLidClosedAction int32 `prop:"access:rw"` - - // 使用电池时,按下电源按钮 关机(默认选择)、待机、睡眠、关闭显示器、无任何操作 - BatteryPressPowerBtnAction int32 `prop:"access:rw"` // keybinding中监听power按键事件,获取gsettings的值 - - // 接通电源时,不做任何操作,到自动锁屏的时间 - LinePowerLockDelay int `prop:"access:rw"` - // 使用电池时,不做任何操作,到自动锁屏的时间 - BatteryLockDelay int `prop:"access:rw"` - - // 打开电量通知 - LowPowerNotifyEnable bool `prop:"access:rw"` // 开启后默认当电池仅剩余达到电量水平低时(默认15%)发出系统通知“电池电量低,请连接电源”; - // 当电池仅剩余为设置低电量时(默认5%),发出系统通知“电池电量耗尽”,进入待机模式; - - // 电池低电量通知百分比 - LowPowerNotifyThreshold int32 `prop:"access:rw"` // 设置电量低提醒的阈值,可设置范围10%-25%,默认为20% - - // 自动待机电量百分比 - LowPowerAutoSleepThreshold int32 `prop:"access:rw"` // 设置电池电量进入待机模式(s3)的阈值,可设置范围为1%-9%,默认为5%(范围待确定) - - // 低电量操作 - LowPowerAction int32 `prop:"access:rw"` - - // dbusutil-gen: ignore-below - - lidSwitchState uint - sessionActive bool - sessionActiveTime time.Time - - // if prepare suspend, ignore idle off - prepareSuspend int - prepareSuspendLocker sync.Mutex - - // 是否支持高性能模式 - IsHighPerformanceSupported bool - gsHighPerformanceEnabled bool - - // 是否支持节能模式 - isPowerSaveSupported bool - kwinHanleIdleOffCh chan bool - - dsDisplayConfigManager configManager.Manager - dsPowerConfigManager configManager.Manager - wmDBus wm.Wm - - delayInActive bool - delayWakeupInterval uint32 - delayHandleIdleOffIntervalWhenScreenBlack uint32 - - // 睡眠前屏幕保护是否正在运行 - screensaverWasRunning bool - // 睡眠前屏幕保护恢复时是否需要密码 - screensaverLockAtAwake bool - // 是否已在进入待机流程前抓取过屏幕保护状态 - screensaverStateCaptured bool - - systemApplicationsMap map[string]string - systemServicesMap map[string]string - shortIdleBlackListApplicationsMap map[string]string -} - -var _manager *Manager - -func copyStringMap(src map[string]string) map[string]string { - dst := make(map[string]string, len(src)) - for key, value := range src { - dst[key] = value - } - return dst -} - -func (m *Manager) systemApplicationsSnapshot() map[string]string { - m.dsgMu.Lock() - defer m.dsgMu.Unlock() - return copyStringMap(m.systemApplicationsMap) -} - -func (m *Manager) replaceSystemApplications(applications []string, getDesktopName func(string) string) { - systemApplicationsMap := make(map[string]string, len(applications)) - for _, app := range applications { - systemApplicationsMap[getDesktopName(app)] = app - } - - m.dsgMu.Lock() - m.systemApplicationsMap = systemApplicationsMap - m.dsgMu.Unlock() -} - -func (m *Manager) systemServicesSnapshot() map[string]string { - m.dsgMu.Lock() - defer m.dsgMu.Unlock() - return copyStringMap(m.systemServicesMap) -} - -func (m *Manager) replaceSystemServices(services []string) { - systemServicesMap := make(map[string]string, len(services)) - for _, service := range services { - systemServicesMap[service] = service - } - - m.dsgMu.Lock() - m.systemServicesMap = systemServicesMap - m.dsgMu.Unlock() -} - -func (m *Manager) shortIdleBlacklistApplicationsSnapshot() map[string]string { - m.dsgMu.Lock() - defer m.dsgMu.Unlock() - return copyStringMap(m.shortIdleBlackListApplicationsMap) -} - -func (m *Manager) replaceShortIdleBlacklistApplications(applications []string, getDesktopName func(string) string) { - shortIdleBlackListApplicationsMap := make(map[string]string, len(applications)) - for _, app := range applications { - shortIdleBlackListApplicationsMap[getDesktopName(app)] = app - } - - m.dsgMu.Lock() - m.shortIdleBlackListApplicationsMap = shortIdleBlackListApplicationsMap - m.dsgMu.Unlock() -} - -func newManager(service *dbusutil.Service) (*Manager, error) { - systemBus, err := dbus.SystemBus() - if err != nil { - return nil, err - } - m := new(Manager) - m.service = service - sessionBus := service.Conn() - m.sessionSigLoop = dbusutil.NewSignalLoop(sessionBus, 10) - m.systemSigLoop = dbusutil.NewSignalLoop(systemBus, 10) - m.objLogin = login1.NewManager(systemBus) - m.ddeShutdown = shutdownfront.NewShutdownFront(sessionBus) - m.displayManager = DisplayManager.NewDisplayManager(systemBus) - m.inhibitFd = -1 - m.prepareSuspend = suspendStateUnknown - - m.syncConfig = dsync.NewConfig("power", &syncConfig{m: m}, m.sessionSigLoop, dbusPath, logger) - - helper, err := newHelper(systemBus, sessionBus) - if err != nil { - return nil, err - } - m.helper = helper - - m.sessionManager = sessionmanager.NewSessionManager(sessionBus) - m.currentSessionPath, err = m.sessionManager.CurrentSessionPath().Get(0) - if err != nil || m.currentSessionPath == "" { - logger.Warning("get sessionManager CurrentSessionPath failed:", err) - return nil, err - } - m.currentSession, err = login1.NewSession(systemBus, m.currentSessionPath) - if err != nil || m.currentSession == nil { - logger.Error("Failed to connect self session:", err) - return nil, err - } - - m.warnLevelConfig = NewWarnLevelConfigManager(m) - m.warnLevelConfig.setChangeCallback(m.handleBatteryDisplayUpdate) - - power := m.helper.Power - err = common.ActivateSysDaemonService(power.ServiceName_()) - if err != nil { - logger.Warning(err) - } - - m.LidIsPresent, err = power.HasLidSwitch().Get(0) - if err != nil { - logger.Warning(err) - } - - m.OnBattery, err = power.OnBattery().Get(0) - if err != nil { - logger.Warning(err) - } - - logger.Info("LidIsPresent", m.LidIsPresent) - - m.sessionActive, _ = helper.SessionWatcher.IsActive().Get(0) - - // init battery display - m.BatteryIsPresent = make(map[string]bool) - m.BatteryPercentage = make(map[string]float64) - m.BatteryState = make(map[string]uint32) - - // 初始化电源模式 - m.systemPower = systemPower.NewPower(systemBus) - - // 绑定org.deepin.dde.Display1的DBus - m.display = display.NewDisplay(sessionBus) - m.wmDBus = wm.NewWm(sessionBus) - - m.calendar = calendar.NewHuangLi(sessionBus) - m.notify = notifications.NewNotifications(sessionBus) - m.notify.InitSignalExt(m.sessionSigLoop, true) - - m.sessionTimeDate = sessiontimedate.NewTimedate(sessionBus) - m.sessionTimeDate.InitSignalExt(m.sessionSigLoop, true) - - m.timeDate = timedate.NewTimedate(systemBus) - m.timeDate.InitSignalExt(m.systemSigLoop, true) - - m.systemApplicationsMap = make(map[string]string) - m.systemServicesMap = make(map[string]string) - m.shortIdleBlackListApplicationsMap = make(map[string]string) - return m, nil -} - -func (m *Manager) init() { - m.sessionSigLoop.Start() - m.systemSigLoop.Start() - - if os.Getenv("XDG_SESSION_TYPE") == "wayland" { - m.UseWayland = true - } else { - m.UseWayland = false - } - - logger.Info("init Getenv(WAYLAND_DISPLAY) UseWayland : ", m.UseWayland) - m.helper.initSignalExt(m.systemSigLoop, m.sessionSigLoop) - - // init sleep inhibitor - m.inhibitor = newSleepInhibitor(m.helper.LoginManager, m.helper.Daemon) - m.inhibitor.OnBeforeSuspend = m.handleBeforeSuspend - m.inhibitor.OnWakeup = m.handleWakeup - err := m.inhibitor.block() - if err != nil { - logger.Warning(err) - } - - m.handleBatteryDisplayUpdate() - power := m.helper.Power - _, err = power.ConnectBatteryDisplayUpdate(func(timestamp int64) { - logger.Debug("BatteryDisplayUpdate", timestamp) - m.handleBatteryDisplayUpdate() - }) - if err != nil { - logger.Warning(err) - } - - _, err = m.helper.SysDBusDaemon.ConnectNameOwnerChanged( - func(name string, oldOwner string, newOwner string) { - if name == m.helper.LoginManager.ServiceName_() && oldOwner != "" && newOwner == "" { - if m.prepareSuspend == suspendStatePrepare { - logger.Info("auto handleWakeup if systemd-logind coredump") - m.handleWakeup() - } - } - }) - if err != nil { - logger.Warning(err) - } - - // 修改时间后通过信号通知更新关机定时器 - _, err = m.sessionTimeDate.ConnectTimeUpdate(func() { - if m.ScheduledShutdownState { - m.setNextShutdownTime(0) - m.scheduledShutdown(Init) - } - }) - if err != nil { - logger.Warning("connect signal TimeUpdate failed:", err) - } - - err = m.timeDate.Timezone().ConnectChanged(func(hasValue bool, value string) { - time.AfterFunc(time.Second*2, func() { - if m.ScheduledShutdownState { - m.setNextShutdownTime(0) - m.scheduledShutdown(Init) - } - }) - }) - if err != nil { - logger.Warning(err) - } - - err = m.timeDate.NTP().ConnectChanged(func(hasValue bool, value bool) { - time.AfterFunc(time.Second*2, func() { - if m.ScheduledShutdownState { - m.setNextShutdownTime(0) - m.scheduledShutdown(Init) - } - }) - }) - if err != nil { - logger.Warning("connect NTP failed:", err) - } - - err = m.helper.SessionWatcher.IsActive().ConnectChanged(func(hasValue bool, value bool) { - if !hasValue { - return - } - - m.PropsMu.Lock() - m.sessionActive = value - m.sessionActiveTime = time.Now() - m.PropsMu.Unlock() - - logger.Debug("session active changed to:", value) - // 出发关机定时器 - m.scheduledShutdown(Init) - }) - if err != nil { - logger.Warning(err) - } - - m.initDsg() - m.initDConfigConnectChanged() - m.initOnBatteryChangedHandler() - m.initSubmodules() - m.startSubmodules() - m.inhibitLogind() - m.initDBusPropCallback() - - m.warnLevelConfig.initDsg() - m.warnLevelConfig.connectSettingsChanged() - - isHighPerformanceSupported, err := m.systemPower.IsHighPerformanceSupported().Get(0) - if err != nil { - logger.Warning("Get systemPower.IsHighPerformanceSupported err :", err) - } - - hignPerformanceEnabled, err := m.dsPowerConfigManager.Value(0, dsettingHighPerformanceEnabled) - if err != nil { - logger.Warning("Get systemPower.IsHighPerformanceEnabled err :", err) - } else { - m.setPropIsHighPerformanceSupported(isHighPerformanceSupported && hignPerformanceEnabled.Value().(bool)) - } - - m.isPowerSaveSupported, err = m.systemPower.IsPowerSaveSupported().Get(0) - if err != nil { - logger.Warning("Get systemPower.IsPowerSaveSupported err :", err) - } - - // TODO: treeland 上idle暂未实现 - //if m.UseWayland { - // m.kwinHanleIdleOffCh = make(chan bool, 10) - // go m.listenEventToHandleIdleOff() - // - // go func() { - // for ch := range m.kwinHanleIdleOffCh { - // if ch { - // m.prepareSuspendLocker.Lock() - // // 如果系统处于suspend状态,不需要在上层通过鼠标键盘事件唤醒系统 - // if m.prepareSuspend >= suspendStatePrepare { - // m.prepareSuspendLocker.Unlock() - // continue - // } - // m.prepareSuspendLocker.Unlock() - // - // logger.Info("kwin handle idle off") - // - // if v := m.submodules[submodulePSP]; v != nil { - // if psp := v.(*powerSavePlan); psp != nil { - // psp.HandleIdleOff() - // } - // } - // } - // } - // }() - //} -} - -func (m *Manager) initDBusPropCallback() { - so := m.service.GetServerObject(m) - if so != nil { - err := so.SetWriteCallback(m, "ScheduledShutdownState", func(write *dbusutil.PropertyWrite) *dbus.Error { - value, ok := write.Value.(bool) - if !ok { - logger.Warning("Type is not bool") - } else { - logger.Info("ScheduledShutdownState change to", value) - } - m.setPropScheduledShutdownState(value) - err := m.savePowerDsgConfig(dsettingScheduledShutdownState) - return dbusutil.ToError(err) - }) - err = so.SetWriteCallback(m, "ShutdownTime", func(write *dbusutil.PropertyWrite) *dbus.Error { - value, ok := write.Value.(string) - if !ok { - logger.Warning("Type is not string") - } else { - logger.Info("ShutdownTime change to", value) - } - m.setPropShutdownTime(value) - err = m.savePowerDsgConfig(dsettingShutdownTime) - return dbusutil.ToError(err) - }) - err = so.SetWriteCallback(m, "ShutdownRepetition", func(write *dbusutil.PropertyWrite) *dbus.Error { - value, ok := write.Value.(int32) - if !ok { - logger.Warning("Type is not int") - } else { - logger.Info("ShutdownRepetition change to", value) - } - m.setPropShutdownRepetition(int(value)) - err = m.savePowerDsgConfig(dsettingShutdownRepetition) - return dbusutil.ToError(err) - }) - err = so.SetWriteCallback(m, "CustomShutdownWeekDays", func(write *dbusutil.PropertyWrite) *dbus.Error { - days := []byte{} - for _, v := range write.Value.([]uint8) { - days = append(days, byte(v)) - } - m.setPropCustomShutdownWeekDays(days) - err = m.savePowerDsgConfig(dsettingCustomShutdownWeekDays) - return dbusutil.ToError(err) - }) - err = so.SetWriteCallback(m, "LinePowerScreensaverDelay", func(write *dbusutil.PropertyWrite) *dbus.Error { - value, ok := write.Value.(int32) - if !ok { - logger.Warning("Type is not int") - } else { - logger.Info("ShutdownRepetition change to", value) - } - m.setPropLinePowerScreensaverDelay(int(value)) - err = m.savePowerDsgConfig(dsettingLinePowerScreensaverDelay) - return dbusutil.ToError(err) - }) - - err = so.SetWriteCallback(m, "BatteryScreensaverDelay", func(write *dbusutil.PropertyWrite) *dbus.Error { - value, ok := write.Value.(int32) - if !ok { - logger.Warning("Type is not int") - } else { - logger.Info("ShutdownRepetition change to", value) - } - m.setPropBatteryScreensaverDelay(int(value)) - err = m.savePowerDsgConfig(dsettingBatteryScreensaverDelay) - return dbusutil.ToError(err) - }) - - err = so.SetWriteCallback(m, "LinePowerScreenBlackDelay", func(write *dbusutil.PropertyWrite) *dbus.Error { - value, ok := write.Value.(int32) - if !ok { - logger.Warning("Type is not int") - } else { - logger.Info("LinePowerScreenBlackDelay change to", value) - } - m.setPropLinePowerScreenBlackDelay(int(value)) - err = m.savePowerDsgConfig(dsettingLinePowerScreenBlackDelay) - return dbusutil.ToError(err) - }) - - err = so.SetWriteCallback(m, "LinePowerSleepDelay", func(write *dbusutil.PropertyWrite) *dbus.Error { - value, ok := write.Value.(int32) - if !ok { - logger.Warning("Type is not int") - } else { - logger.Info("LinePowerSleepDelay change to", value) - } - m.setPropLinePowerSleepDelay(int(value)) - err = m.savePowerDsgConfig(dsettingLinePowerSleepDelay) - return dbusutil.ToError(err) - }) - - err = so.SetWriteCallback(m, "LinePowerLockDelay", func(write *dbusutil.PropertyWrite) *dbus.Error { - value, ok := write.Value.(int32) - if !ok { - logger.Warning("Type is not int") - } else { - logger.Info("LinePowerLockDelay change to", value) - } - m.setPropLinePowerLockDelay(int(value)) - err = m.savePowerDsgConfig(dsettingLinePowerLockDelay) - return dbusutil.ToError(err) - }) - - err = so.SetWriteCallback(m, "BatteryScreenBlackDelay", func(write *dbusutil.PropertyWrite) *dbus.Error { - value, ok := write.Value.(int32) - if !ok { - logger.Warning("Type is not int") - } else { - logger.Info("BatteryScreenBlackDelay change to", value) - } - m.setPropBatteryScreenBlackDelay(int(value)) - err = m.savePowerDsgConfig(dsettingBatteryScreenBlackDelay) - return dbusutil.ToError(err) - }) - - err = so.SetWriteCallback(m, "BatterySleepDelay", func(write *dbusutil.PropertyWrite) *dbus.Error { - value, ok := write.Value.(int32) - if !ok { - logger.Warning("Type is not int") - } else { - logger.Info("BatterySleepDelay change to", value) - } - m.setPropBatterySleepDelay(int(value)) - err = m.savePowerDsgConfig(dsettingBatterySleepDelay) - return dbusutil.ToError(err) - }) - - err = so.SetWriteCallback(m, "BatteryLockDelay", func(write *dbusutil.PropertyWrite) *dbus.Error { - value, ok := write.Value.(int32) - if !ok { - logger.Warning("Type is not int") - } else { - logger.Info("BatteryLockDelay change to", value) - } - m.setPropBatteryLockDelay(int(value)) - err = m.savePowerDsgConfig(dsettingBatteryLockDelay) - return dbusutil.ToError(err) - }) - - err = so.SetWriteCallback(m, "ScreenBlackLock", func(write *dbusutil.PropertyWrite) *dbus.Error { - value, ok := write.Value.(bool) - if !ok { - logger.Warning("Type is not bool") - } else { - logger.Info("ScreenBlackLock change to", value) - } - m.setPropScreenBlackLock(value) - err = m.savePowerDsgConfig(dsettingScreenBlackLock) - return dbusutil.ToError(err) - }) - - err = so.SetWriteCallback(m, "SleepLock", func(write *dbusutil.PropertyWrite) *dbus.Error { - value, ok := write.Value.(bool) - if !ok { - logger.Warning("Type is not bool") - } else { - logger.Info("SleepLock change to", value) - } - m.setPropSleepLock(value) - err = m.savePowerDsgConfig(dsettingSleepLock) - return dbusutil.ToError(err) - }) - - err = so.SetWriteCallback(m, "LinePowerLidClosedAction", func(write *dbusutil.PropertyWrite) *dbus.Error { - value, ok := write.Value.(int32) - if !ok { - logger.Warning("Type is not int") - } else { - logger.Info("LinePowerLidClosedAction change to", value) - } - m.setPropLinePowerLidClosedAction(value) - err = m.savePowerDsgConfig(dsettingLinePowerLidClosedAction) - return dbusutil.ToError(err) - }) - - err = so.SetWriteCallback(m, "LinePowerPressPowerBtnAction", func(write *dbusutil.PropertyWrite) *dbus.Error { - value, ok := write.Value.(int32) - if !ok { - logger.Warning("Type is not int") - } else { - logger.Info("LinePowerPressPowerBtnAction change to", value) - } - m.setPropLinePowerPressPowerBtnAction(value) - m.LinePowerPressPowerBtnAction = value - err = m.savePowerDsgConfig(dsettingLinePowerPressPowerButton) - return dbusutil.ToError(err) - }) - - err = so.SetWriteCallback(m, "BatteryLidClosedAction", func(write *dbusutil.PropertyWrite) *dbus.Error { - value, ok := write.Value.(int32) - if !ok { - logger.Warning("Type is not int") - } else { - logger.Info("BatteryLidClosedAction change to", value) - } - m.setPropBatteryLidClosedAction(value) - err = m.savePowerDsgConfig(dsettingBatteryLidClosedAction) - return dbusutil.ToError(err) - }) - - err = so.SetWriteCallback(m, "BatteryPressPowerBtnAction", func(write *dbusutil.PropertyWrite) *dbus.Error { - value, ok := write.Value.(int32) - if !ok { - logger.Warning("Type is not int") - } else { - logger.Info("BatteryPressPowerBtnAction change to", value) - } - m.setPropBatteryPressPowerBtnAction(value) - err = m.savePowerDsgConfig(dsettingBatteryPressPowerButton) - return dbusutil.ToError(err) - }) - - err = so.SetWriteCallback(m, "LowPowerNotifyEnable", func(write *dbusutil.PropertyWrite) *dbus.Error { - value, ok := write.Value.(bool) - if !ok { - logger.Warning("Type is not bool") - } else { - logger.Info("LowPowerNotifyEnable change to", value) - } - m.setPropLowPowerNotifyEnable(value) - err = m.savePowerDsgConfig(dsettingLowPowerNotifyEnable) - return dbusutil.ToError(err) - }) - - err = so.SetWriteCallback(m, "LowPowerAction", func(write *dbusutil.PropertyWrite) *dbus.Error { - value, ok := write.Value.(int32) - if !ok { - logger.Warning("Type is not int") - } else { - logger.Info("LowPowerAction change to", value) - } - m.setPropLowPowerAction(value) - err = m.savePowerDsgConfig(dsettingLowPowerAction) - return dbusutil.ToError(err) - }) - - err = so.SetWriteCallback(m, "LinePowerShortIdleDelay", func(write *dbusutil.PropertyWrite) *dbus.Error { - value, ok := write.Value.(int32) - if !ok { - logger.Warning("Type is not int32") - } else { - logger.Info("LinePowerShortIdleDelay change to", value) - } - m.setPropLinePowerShortIdleDelay(int(value)) - err = m.savePowerDsgConfig(dsettingsLinePowerShortIdleDelay) - return dbusutil.ToError(err) - }) - - err = so.SetWriteCallback(m, "BatteryShortIdleDelay", func(write *dbusutil.PropertyWrite) *dbus.Error { - value, ok := write.Value.(int32) - if !ok { - logger.Warning("Type is not int32") - } else { - logger.Info("BatteryShortIdleDelay change to", value) - } - m.setPropBatteryShortIdleDelay(int(value)) - err = m.savePowerDsgConfig(dsettingsBatteryShortIdleDelay) - return dbusutil.ToError(err) - }) - - err = so.SetWriteCallback(m, "LowPowerAutoSleepThreshold", func(write *dbusutil.PropertyWrite) *dbus.Error { - value, ok := write.Value.(int32) - if !ok { - logger.Warning("Type is not int32") - } else { - logger.Info("LowPowerAutoSleepThreshold change to", value) - } - m.setPropLowPowerAutoSleepThreshold(value) - err = m.savePowerDsgConfig(dsettingPercentageAction) - return dbusutil.ToError(err) - }) - - err = so.SetWriteCallback(m, "LowPowerNotifyThreshold", func(write *dbusutil.PropertyWrite) *dbus.Error { - value, ok := write.Value.(int32) - if !ok { - logger.Warning("Type is not int32") - } else { - logger.Info("LowPowerNotifyThreshold change to", value) - } - m.setPropLowPowerNotifyThreshold(value) - err = m.savePowerDsgConfig(dsettingLowPowerNotifyThreshold) - return dbusutil.ToError(err) - }) - - } -} - -func (m *Manager) destroy() { - m.destroySubmodules() - m.permitLogind() - - if m.helper != nil { - m.helper.Destroy() - m.helper = nil - } - - if m.inhibitor != nil { - err := m.inhibitor.unblock() - if err != nil { - logger.Warning(err) - } - m.inhibitor = nil - } - - m.systemSigLoop.Stop() - m.sessionSigLoop.Stop() - m.syncConfig.Destroy() -} - -func (*Manager) GetInterfaceName() string { - return dbusInterface -} - -func (m *Manager) Reset() *dbus.Error { - logger.Debug("Reset settings") - - var settingKeys = []string{ - dsettingLinePowerScreenBlackDelay, - dsettingLinePowerSleepDelay, - dsettingLinePowerLockDelay, - dsettingLinePowerLidClosedAction, - dsettingLinePowerPressPowerButton, - - dsettingBatteryScreenBlackDelay, - dsettingBatterySleepDelay, - dsettingBatteryLockDelay, - dsettingBatteryLidClosedAction, - dsettingBatteryPressPowerButton, - - dsettingScreenBlackLock, - dsettingSleepLock, - dsettingPowerButtonPressedExec, - - dsettingLowPowerNotifyEnable, - dsettingLowPowerNotifyThreshold, - dsettingPercentageAction, - - dsettingsLinePowerShortIdleDelay, - dsettingsBatteryShortIdleDelay, - } - for _, key := range settingKeys { - logger.Debug("reset setting", key) - m.dsPowerConfigManager.Reset(0, key) - } - return nil -} - -func (m *Manager) initDsg() { - systemBus, err := dbus.SystemBus() - if err != nil { - return - } - - dsg := configManager.NewConfigManager(systemBus) - if !dutils.IsFileExist("/usr/share/dsg/configs/org.deepin.dde.daemon/org.deepin.Display.json") { - logger.Warning(" [initDsg] dconfig file not exist : /usr/share/dsg/configs/org.deepin.dde.daemon/org.deepin.Display.json.") - } else { - // display - displayConfigManagerPath, err := dsg.AcquireManager(0, DSettingsAppID, DSettingsDisplayName, "") - if err != nil { - logger.Warning(err) - return - } - - m.dsDisplayConfigManager, err = configManager.NewManager(systemBus, displayConfigManagerPath) - if err != nil || displayConfigManagerPath == "" { - logger.Warning(err) - } - } - - // power - powerConfigManagerPath, err := dsg.AcquireManager(0, dsettingsAppID, dsettingsPowerName, "") - if err != nil { - logger.Warning(err) - return - } - m.dsPowerConfigManager, err = configManager.NewManager(systemBus, powerConfigManagerPath) - if err != nil { - logger.Warning(err) - return - } - - transTypeToInt := func(v interface{}, def int64) int64 { - switch v := v.(type) { - case int64: - return v - case float64: - return int64(v) - } - return def - } - getDsPowerConfig := func(key string, init bool) { - data, err := m.dsPowerConfigManager.Value(0, key) - if err != nil { - logger.Warning(err) - return - } - switch key { - case dsettingCustomShutdownWeekDays: - res := []byte{} - for _, v := range data.Value().([]dbus.Variant) { - res = append(res, byte(transTypeToInt(v.Value(), 0))) - } - if init { - m.CustomShutdownWeekDays = res - return - } - if m.setPropCustomShutdownWeekDays(res) { - logger.Info("Set CustomShutdownWeekDays property", m.CustomShutdownWeekDays) - } - case dsettingShutdownCountdown: - m.shutdownCountdown = int(transTypeToInt(data.Value(), 60)) - case dsettingNextShutdownTime: - m.nextShutdownTime = int64(transTypeToInt(data.Value(), 0)) - case dsettingShutdownRepetition: - if init { - m.ShutdownRepetition = int(transTypeToInt(data.Value(), 0)) - return - } - if m.setPropShutdownRepetition(int(transTypeToInt(data.Value(), 0))) { - logger.Info("Set ShutdownRepetition property", m.ShutdownRepetition) - } - case dsettingShutdownTime: - if init { - m.ShutdownTime = data.Value().(string) - return - } - if m.setPropShutdownTime(data.Value().(string)) { - logger.Info("Set ShutdownTime property", m.ShutdownTime) - } - case dsettingScheduledShutdownState: - if init { - m.ScheduledShutdownState = data.Value().(bool) - } else { - if m.setPropScheduledShutdownState(data.Value().(bool)) { - logger.Info("Set ScheduledShutdownState property", m.ScheduledShutdownState) - } - } - case dsettingLinePowerScreensaverDelay: - m.LinePowerScreensaverDelay = int(transTypeToInt(data.Value(), 0)) - case dsettingBatteryScreensaverDelay: - m.BatteryScreensaverDelay = int(transTypeToInt(data.Value(), 0)) - case dsettingBatteryScreenBlackDelay: - m.BatteryScreenBlackDelay = int(transTypeToInt(data.Value(), 0)) - case dsettingBatterySleepDelay: - m.BatterySleepDelay = int(transTypeToInt(data.Value(), 0)) - case dsettingLinePowerScreenBlackDelay: - m.LinePowerScreenBlackDelay = int(transTypeToInt(data.Value(), 0)) - case dsettingLinePowerSleepDelay: - m.LinePowerSleepDelay = int(transTypeToInt(data.Value(), 0)) - case dsettingLinePowerLockDelay: - m.LinePowerLockDelay = int(transTypeToInt(data.Value(), 0)) - case dsettingBatteryLockDelay: - m.BatteryLockDelay = int(transTypeToInt(data.Value(), 0)) - case dsettingScreenBlackLock: - m.ScreenBlackLock = data.Value().(bool) - case dsettingSleepLock: - m.SleepLock = data.Value().(bool) - case dsettingLowPowerAction: - m.LowPowerAction = int32(transTypeToInt(data.Value(), 0)) - case dsettingLinePowerLidClosedAction: - m.LinePowerLidClosedAction = int32(transTypeToInt(data.Value(), 0)) - case dsettingLinePowerPressPowerButton: - m.LinePowerPressPowerBtnAction = int32(transTypeToInt(data.Value(), 0)) - case dsettingBatteryLidClosedAction: - m.BatteryLidClosedAction = int32(transTypeToInt(data.Value(), 0)) - case dsettingBatteryPressPowerButton: - m.BatteryPressPowerBtnAction = int32(transTypeToInt(data.Value(), 0)) - case dsettingLowPowerNotifyEnable: - m.LowPowerNotifyEnable = data.Value().(bool) - case dsettingHighPerformanceEnabled: - m.gsHighPerformanceEnabled = data.Value().(bool) - case dsettingLowPowerNotifyThreshold: - m.LowPowerNotifyThreshold = int32(transTypeToInt(data.Value(), 0)) - case dsettingPercentageAction: - m.LowPowerAutoSleepThreshold = int32(transTypeToInt(data.Value(), 0)) - case dsettingsLinePowerShortIdleDelay: - m.LinePowerShortIdleDelay = int(transTypeToInt(data.Value(), 300)) - case dsettingsBatteryShortIdleDelay: - m.BatteryShortIdleDelay = int(transTypeToInt(data.Value(), 300)) - } - - // m.scheduledShutdownSwitch(false, false) - // m.scheduledShutdownSwitch(m.ScheduledShutdownState, false) - - } - - getDsPowerConfig(dsettingCustomShutdownWeekDays, true) - getDsPowerConfig(dsettingShutdownCountdown, true) - getDsPowerConfig(dsettingShutdownRepetition, true) - getDsPowerConfig(dsettingShutdownTime, true) - getDsPowerConfig(dsettingScheduledShutdownState, true) - getDsPowerConfig(dsettingNextShutdownTime, true) - getDsPowerConfig(dsettingLinePowerScreensaverDelay, true) - getDsPowerConfig(dsettingBatteryScreensaverDelay, true) - getDsPowerConfig(dsettingBatteryScreenBlackDelay, true) - getDsPowerConfig(dsettingBatterySleepDelay, true) - getDsPowerConfig(dsettingLinePowerScreenBlackDelay, true) - getDsPowerConfig(dsettingLinePowerSleepDelay, true) - getDsPowerConfig(dsettingLinePowerLockDelay, true) - getDsPowerConfig(dsettingBatteryLockDelay, true) - getDsPowerConfig(dsettingScreenBlackLock, true) - getDsPowerConfig(dsettingSleepLock, true) - getDsPowerConfig(dsettingLowPowerAction, true) - getDsPowerConfig(dsettingLinePowerLidClosedAction, true) - getDsPowerConfig(dsettingLinePowerPressPowerButton, true) - getDsPowerConfig(dsettingBatteryLidClosedAction, true) - getDsPowerConfig(dsettingBatteryPressPowerButton, true) - getDsPowerConfig(dsettingLowPowerNotifyEnable, true) - getDsPowerConfig(dsettingHighPerformanceEnabled, true) - getDsPowerConfig(dsettingLowPowerNotifyThreshold, true) - getDsPowerConfig(dsettingPercentageAction, true) - getDsPowerConfig(dsettingsLinePowerShortIdleDelay, true) - getDsPowerConfig(dsettingsBatteryShortIdleDelay, true) - - m.dsPowerConfigManager.InitSignalExt(m.systemSigLoop, true) - m.dsPowerConfigManager.ConnectValueChanged(func(key string) { - if key == dsettingNextShutdownTime { - return - } - logger.Info("DSG org.deepin.dde.daemon.power valueChanged, key : ", key) - getDsPowerConfig(key, false) - // 如果重复一次,重置nextShutdownTime - if m.ScheduledShutdownState { - m.setNextShutdownTime(0) - } - m.scheduledShutdown(Init) - }) - - if m.nextShutdownTime == 0 { - m.setNextShutdownTime(0) - } - m.scheduledShutdown(Init) -} - -func (m *Manager) setNextShutdownTime(bt int64) { - m.nextShutdownTime = m.getNextShutdownTime(bt) - m.savePowerDsgConfig(dsettingNextShutdownTime) -} - -func (m *Manager) savePowerDsgConfig(key string) (err error) { - var value interface{} - switch key { - case dsettingCustomShutdownWeekDays: - var tmp []dbus.Variant - for _, v := range m.CustomShutdownWeekDays { - tmp = append(tmp, dbus.MakeVariant(float64(v))) - } - value = tmp - case dsettingShutdownCountdown: - value = m.shutdownCountdown - case dsettingNextShutdownTime: - value = m.nextShutdownTime - case dsettingShutdownRepetition: - value = m.ShutdownRepetition - case dsettingShutdownTime: - value = m.ShutdownTime - case dsettingScheduledShutdownState: - value = m.ScheduledShutdownState - case dsettingLinePowerScreensaverDelay: - value = m.LinePowerScreensaverDelay - case dsettingBatteryScreensaverDelay: - value = m.BatteryScreensaverDelay - case dsettingBatteryScreenBlackDelay: - value = m.BatteryScreenBlackDelay - case dsettingBatterySleepDelay: - value = m.BatterySleepDelay - case dsettingLinePowerScreenBlackDelay: - value = m.LinePowerScreenBlackDelay - case dsettingLinePowerSleepDelay: - value = m.LinePowerSleepDelay - case dsettingLinePowerLockDelay: - value = m.LinePowerLockDelay - case dsettingBatteryLockDelay: - value = m.BatteryLockDelay - case dsettingScreenBlackLock: - value = m.ScreenBlackLock - case dsettingSleepLock: - value = m.SleepLock - case dsettingLowPowerAction: - value = m.LowPowerAction - case dsettingLinePowerLidClosedAction: - value = m.LinePowerLidClosedAction - case dsettingLinePowerPressPowerButton: - value = m.LinePowerPressPowerBtnAction - case dsettingBatteryLidClosedAction: - value = m.BatteryLidClosedAction - case dsettingBatteryPressPowerButton: - value = m.BatteryPressPowerBtnAction - case dsettingLowPowerNotifyEnable: - value = m.LowPowerNotifyEnable - case dsettingHighPerformanceEnabled: - value = m.gsHighPerformanceEnabled - case dsettingLowPowerNotifyThreshold: - value = m.LowPowerNotifyThreshold - case dsettingPercentageAction: - value = m.LowPowerAutoSleepThreshold - case dsettingsLinePowerShortIdleDelay: - value = m.LinePowerShortIdleDelay - case dsettingsBatteryShortIdleDelay: - value = m.BatteryShortIdleDelay - } - err = m.setDsgData(key, value, m.dsPowerConfigManager) - if err != nil { - logger.Warning(err) - return err - } - return nil -} - -func (m *Manager) setDsgData(key string, value interface{}, dsg configManager.Manager) error { - if dsg == nil { - return errors.New("setDsgData dsg is nil") - } - if value == nil { - return errors.New("setDsgData value is nil") - } - err := dsg.SetValue(0, key, dbus.MakeVariant(value)) - if err != nil { - logger.Warningf("setDsgData key : %s. err : %v", key, err) - return err - } - logger.Infof("setDsgData key : %s , value : %v", key, value) - return nil -} - -const ( - Init = iota // 初始阶段 - WaitingToNotify // 等待发送通知 - Countdowning // 倒计时中 - // 下面是执行结果 - Shutdown // 倒计时结束,准备关机 - Cancle // 执行关机取消,可能需要重置定时器 - TimeOut // 检测到超时,可能需要重置定时器 -) - -func (m *Manager) scheduledShutdown(state int) { - logger.Debugf("scheduledShutdown,pre-stat:%v next-stat:%v nextShutDownTime:%v", m.shutdownStatus, state, time.Unix(m.nextShutdownTime, 0).Format("2006-01-02 15:04:05")) - if m.shutdownTimer != nil { - m.shutdownTimer.Stop() - m.shutdownTimer = nil - } - - // 用户非活跃状态或者低电量屏保状态,停止定时关机流程 - isSessionActive, _ := m.helper.SessionWatcher.IsActive().Get(0) - if !isSessionActive || m.WarnLevel == WarnLevelAction { - m.notify.CloseNotification(0, m.notifyId) - logger.Warning("Stop scheduledShutdown") - return - } - - if state != Init && state == m.shutdownStatus { - return - } - - // 下次关机时间为0,则退出调度 - if m.nextShutdownTime == 0 { - logger.Warning("next shutdown time is illegal, please check the config") - return - } - - next := time.Unix(m.nextShutdownTime, 0) - currentTime := time.Now() - switch state { - case Init: - // 定时关闭的情况下,关闭定时器 - if m.shutdownStatus >= Countdowning { - m.notify.CloseNotification(0, m.notifyId) - } - if !m.ScheduledShutdownState { - return - } - m.shutdownStatus = Init - var nextStatus int - logger.Debugf("shutdown sub:%v s, %v min, countDown:%v", int(next.Sub(currentTime).Seconds()), int(next.Sub(currentTime).Minutes()), m.shutdownCountdown) - if int(next.Sub(currentTime).Minutes()) < 0 { - // 超时太久,则进行超时处理 - nextStatus = TimeOut - } else if int(next.Sub(currentTime).Minutes()) == 0 { - // 超时太久,则进行超时处理 - nextStatus = Countdowning - } else if int(next.Sub(currentTime).Seconds()) <= m.shutdownCountdown { - // 如果在倒计时的时区内 - nextStatus = Countdowning - } else { - // 时间远远未到,等待发送通知 - nextStatus = WaitingToNotify - } - m.scheduledShutdown(nextStatus) - case WaitingToNotify: - m.shutdownStatus = WaitingToNotify - // 提前通知,设置通知的定时器 - t := time.Duration(m.shutdownCountdown) * time.Second * -1 - next = next.Add(t) - m.shutdownTimer = time.AfterFunc(time.Until(next), func() { - m.scheduledShutdown(Countdowning) - }) - case Countdowning: - m.shutdownStatus = Countdowning - // 已经发送通知,正在进行关机倒计时 - counter := func() func() int { - count := m.shutdownCountdown + 1 - return func() int { - count-- - return count - } - }() - go func() { - count := counter() - m.shutdownCountdownNotify(count, true) - m.shutdownTimer = time.NewTimer(time.Second) - for range m.shutdownTimer.C { - count := counter() - if count == 0 { - m.scheduledShutdown(Shutdown) - } else { - // TODO: 每秒通知一次?有没有更好的办法? - m.shutdownCountdownNotify(count, false) - m.shutdownTimer.Reset(time.Second) - } - } - }() - case Shutdown, Cancle, TimeOut: - // 如果是超时,则关闭通知 - if state == TimeOut { - m.notify.CloseNotification(0, m.notifyId) - } - m.shutdownStatus = state - if m.ShutdownRepetition == Once { - // 如果是重复一次,则停止定时器 - m.setPropScheduledShutdownState(false) - m.nextShutdownTime = 0 - m.savePowerDsgConfig(dsettingNextShutdownTime) - m.savePowerDsgConfig(dsettingScheduledShutdownState) - } else { - // 重新生成下一次定时关机时间,并保存 - m.setNextShutdownTime(m.nextShutdownTime) - // 当前与设定的时间超过1分钟 - t := time.Until(next).Minutes() - if t > 0 { - // 超时,重新开始调度 - m.shutdownTimer = time.AfterFunc(10*time.Second, func() { - m.scheduledShutdown(Init) - }) - } else { - // 提前取消,则等待count时间后在重新调度 - m.shutdownTimer = time.AfterFunc(time.Duration(m.shutdownCountdown)*time.Second, func() { - m.scheduledShutdown(Init) - }) - } - } - if state == Shutdown { - // 执行关机,整个状态机应该结束了 - m.notify.CloseNotification(0, m.notifyId) - m.doAutoShutdown() - } - } -} - -func (m *Manager) shutdownCountdownNotify(count int, playSound bool) { - body := fmt.Sprintf(gettext.Tr("The system will shut down automatically after %d s"), count) - title := gettext.Tr("Scheduled Shutdown") - actions := []string{"Cancle", gettext.Tr("Cancle"), "Shutdown", gettext.Tr("Shut down")} - hints := map[string]dbus.Variant{"x-deepin-PlaySound": dbus.MakeVariant(playSound), - "urgency": dbus.MakeVariant(2), //取消关闭按钮 - "x-deepin-ShowInNotifyCenter": dbus.MakeVariant(false), - "x-deepin-ClickToDisappear": dbus.MakeVariant(false), - "x-deepin-DisappearAfterLock": dbus.MakeVariant(false)} - m.notifyIdMu.Lock() - nid := m.notifyId - m.notifyIdMu.Unlock() - nid, err := m.notify.Notify(0, "dde-control-center", nid, "preferences-system", title, body, actions, hints, -1) - if err != nil { - logger.Warningf("failed to send notify: %s", err) - } - m.notifyIdMu.Lock() - m.notifyId = nid - m.notifyIdMu.Unlock() - m.notify.ConnectActionInvoked(func(id uint32, actionKey string) { - - var nextStatus int - if actionKey == "Cancle" { - // m.actionShutdown(true) - nextStatus = Cancle - } else if actionKey == "Shutdown" { - // m.actionShutdown(false) - // 执行关机 - nextStatus = Shutdown - } else { - logger.Warningf("unknown actionKey %v", actionKey) - nextStatus = Cancle - } - logger.Warning("notify Invoked:", actionKey) - m.scheduledShutdown(nextStatus) - }) -} - -func (m *Manager) isWorkday(date time.Time) (res bool) { - year, month, _ := date.Date() - val, err := m.calendar.GetFestivalMonth(0, uint32(year), uint32(month)) - if err == nil { - var rootCfg []FestivalRootConfig - err = json.Unmarshal([]byte(val), &rootCfg) - if err != nil { - logger.Warning(err) - return false - } - // 如果list不包含,则按正常周末处理,如果包含,则判断status状态 - if len(rootCfg) <= 0 { - return date.Weekday() != time.Sunday && date.Weekday() != time.Saturday - } - for _, holidayInfo := range rootCfg[0].List { - // 尝试多种日期格式匹配 - dateStr1 := date.Format("2006-1-2") - dateStr2 := date.Format("2006-01-02") - if holidayInfo.Date == dateStr1 || holidayInfo.Date == dateStr2 { - return holidayInfo.Status == 2 - } - } - return date.Weekday() != time.Sunday && date.Weekday() != time.Saturday - } else { - logger.Warning(err) - } - return -} - -func (m *Manager) isCustomday(date time.Time) (res bool) { - for _, v := range m.CustomShutdownWeekDays { - if byte(date.Weekday()) == v { - logger.Debug("Today is included in custom shutdown weekdays") - return true - } - } - return false -} - -const ( - daysOfWeek = 7 //一周天数 - daysOfYear = 366 // 一年天数 -) - -func (m *Manager) getNextShutdownTime(bt int64) int64 { - getNextTime := func() time.Time { - bastTime := time.Unix(bt, 0) - currentTime := time.Now() - // 构建目标时间 - targetTimeLayout := "15:04" - targetTime, _ := time.Parse(targetTimeLayout, m.ShutdownTime) - targetTime = time.Date(currentTime.Year(), currentTime.Month(), currentTime.Day(), targetTime.Hour(), targetTime.Minute(), 0, 0, currentTime.Location()) - // 如果比当前时间小,则跳过今天 - if int(targetTime.Sub(currentTime).Minutes()) < 0 { - // 如果在同一分鐘內,應該立发送通知 - t, _ := time.ParseDuration("24h") - targetTime = targetTime.Add(t) - } - // 如果比base时间小,则target时间加1天 - if int(targetTime.Sub(bastTime).Minutes()) <= 0 { - // 如果在同一分鐘內,應該立发送通知 - t, _ := time.ParseDuration("24h") - targetTime = targetTime.Add(t) - } - return targetTime - } - - var targetTime time.Time - switch m.ShutdownRepetition { - case Once, Everyday: - targetTime = getNextTime() - case Workdays: - targetTime = getNextTime() - // 获取下一个工作日,也可能是今天 - // isWorkday依赖第三方接口,防止调用一直报错导致死循环 - for i := 0; i <= daysOfYear; i++ { - if i == daysOfYear { - return 0 - } - if m.isWorkday(targetTime) { - break - } else { - t, _ := time.ParseDuration("24h") - targetTime = targetTime.Add(t) - } - } - case Custom: - targetTime = getNextTime() - // 一周7天,获取下一个自定义工作日,也可能是今天 - for i := 0; i <= daysOfWeek; i++ { - // 循环一周都获取不到工作日,则返回无效日期 - if i == daysOfWeek { - return 0 - } - if m.isCustomday(targetTime) { - break - } else { - t, _ := time.ParseDuration("24h") - targetTime = targetTime.Add(t) - } - } - } - logger.Debug("gen next shutdown time:", targetTime.Format("2006-01-02 15:04:05")) - return targetTime.Unix() -} - -func (m *Manager) getAutoChangeDeepinWm() bool { - if m.dsDisplayConfigManager == nil { - logger.Warning("getAutoChangeDeepinWm, dsgConfig org.deepin.dde.daemon auto-change-deepin-wm not exist") - return false - } - v, err := m.dsDisplayConfigManager.Value(0, DSettingsAutoChangeWm) - if err != nil { - logger.Warning(err) - return false - } - dsAutoChangeDeepinWm := v.Value().(bool) - logger.Info("Auto Change Deepin Wm:", dsAutoChangeDeepinWm) - - return dsAutoChangeDeepinWm -} - -func (m *Manager) setAutoChangeDeepinWm(value bool) error { - if m.dsDisplayConfigManager == nil { - return errors.New("setAutoChangeDeepinWm, dsgConfig org.deepin.dde,daemon auto-change-deepin-wm not exist") - } - err := m.dsDisplayConfigManager.SetValue(0, DSettingsAutoChangeWm, dbus.MakeVariant(value)) - if err != nil { - return err - } - return nil -} - -func (m *Manager) inhibitLogind() { - inhibit := func() { - fd, err := m.helper.LoginManager.Inhibit(0, - "handle-power-key:handle-lid-switch:handle-suspend-key", dbusServiceName, - "handling key press and lid switch close", "block") - logger.Debug("inhibitLogind fd:", fd) - if err != nil { - logger.Warning(err) - return - } - m.inhibitFd = fd - } - inhibit() - // handle login1 restart - dbusObj := ofdbus.NewDBus(m.systemSigLoop.Conn()) - sysLoop := dbusutil.NewSignalLoop(m.systemSigLoop.Conn(), 10) - sysLoop.Start() - dbusObj.InitSignalExt(sysLoop, true) - _, _ = dbusObj.ConnectNameOwnerChanged(func(name string, oldOwner string, newOwner string) { - if name == "org.freedesktop.login1" && newOwner != "" && oldOwner == "" { - if m.inhibitFd != -1 { // 如果之前存在inhibit时,login1重启需要重新inhibit - err := syscall.Close(int(m.inhibitFd)) - m.inhibitFd = -1 - if err != nil { - logger.Warning("failed to close fd:", err) - return - } - inhibit() - } - } - }) - // end handle login1 restart -} - -func (m *Manager) permitLogind() { - if m.inhibitFd != -1 { - err := syscall.Close(int(m.inhibitFd)) - if err != nil { - logger.Warning("failed to close inhibitFd:", err) - } - m.inhibitFd = -1 - } -} - -func (m *Manager) SetPrepareSuspend(suspendState int) *dbus.Error { - m.setPrepareSuspend(suspendState) - return nil -} - -func (m *Manager) isSessionActive() bool { - active, err := m.currentSession.Active().Get(dbus.FlagNoAutoStart) - if err != nil { - logger.Error("failed to get session active status:", err) - return false - } - return active -} - -// wayland下在收到键盘或者鼠标事件后,需要进行系统空闲处理(主要是唤醒屏幕) -func (m *Manager) listenEventToHandleIdleOff() error { - // + 监控按键事件 - err := m.systemSigLoop.Conn().Object("org.deepin.dde.Gesture1", - "/org/deepin/dde/Gesture1").AddMatchSignal("org.deepin.dde.Gesture1", "KeyboardEvent").Err - if err != nil { - logger.Warning(err) - return err - } - - m.systemSigLoop.AddHandler(&dbusutil.SignalRule{ - Name: "org.deepin.dde.Gesture1.KeyboardEvent", - }, func(sig *dbus.Signal) { - if len(sig.Body) > 1 { - value := sig.Body[1].(uint32) - if m.getDPMSMode() != dpmsStateOn && value == 1 { - logger.Debug("receive keyboard event to handle idle off") - m.kwinHanleIdleOffCh <- true - } - } - }) - - // + 监控鼠标移动事件 - err = m.sessionSigLoop.Conn().Object("org.deepin.dde.KWayland1", - "/org/deepin/dde/KWayland1/Output").AddMatchSignal("org.deepin.dde.KWayland1.Output", "CursorMove").Err - if err != nil { - logger.Warning(err) - return err - } - m.sessionSigLoop.AddHandler(&dbusutil.SignalRule{ - Name: "org.deepin.dde.KWayland1.Output.CursorMove", - }, func(sig *dbus.Signal) { - if len(sig.Body) > 1 { - if m.getDPMSMode() != dpmsStateOn { - logger.Debug("receive cursor move event to handle idle off") - m.kwinHanleIdleOffCh <- true - } - } - }) - - // + 监控鼠标按下事件 - err = m.sessionSigLoop.Conn().Object("org.deepin.dde.KWayland1", - "/org/deepin/dde/KWayland1/Output").AddMatchSignal("org.deepin.dde.KWayland1.Output", "ButtonPress").Err - if err != nil { - logger.Warning(err) - return err - } - m.sessionSigLoop.AddHandler(&dbusutil.SignalRule{ - Name: "org.deepin.dde.KWayland1.Output.ButtonPress", - }, func(sig *dbus.Signal) { - if len(sig.Body) > 1 { - if m.getDPMSMode() != dpmsStateOn { - logger.Debug("acquire button press to handle idle off") - m.kwinHanleIdleOffCh <- true - } - } - }) - - return nil -} diff --git a/session/power1/manager_events.go b/session/power1/manager_events.go deleted file mode 100644 index 3a415d495..000000000 --- a/session/power1/manager_events.go +++ /dev/null @@ -1,333 +0,0 @@ -// SPDX-FileCopyrightText: 2018 - 2022 UnionTech Software Technology Co., Ltd. -// -// SPDX-License-Identifier: GPL-3.0-or-later - -package power - -import ( - "time" - - dbus "github.com/godbus/dbus/v5" - "github.com/linuxdeepin/dde-api/soundutils" - . "github.com/linuxdeepin/go-lib/gettext" -) - -// nolint -const ( - suspendStateUnknown = iota + 1 - suspendStateLidOpen - suspendStateLidClose - suspendStateFinish - suspendStateWakeup - suspendStatePrepare - suspendStateButtonClick -) - -func (m *Manager) setPrepareSuspend(v int) { - m.prepareSuspendLocker.Lock() - m.prepareSuspend = v - m.prepareSuspendLocker.Unlock() -} - -func (m *Manager) shouldIgnoreIdleOn() bool { - m.prepareSuspendLocker.Lock() - v := (m.prepareSuspend > suspendStateFinish) - m.prepareSuspendLocker.Unlock() - return v -} - -func (m *Manager) shouldIgnoreIdleOff() bool { - m.prepareSuspendLocker.Lock() - v := (m.prepareSuspend >= suspendStatePrepare) - m.prepareSuspendLocker.Unlock() - return v -} - -// 处理有线电源插入拔出事件 -func (m *Manager) initOnBatteryChangedHandler() { - power := m.helper.Power - err := power.OnBattery().ConnectChanged(func(hasValue bool, onBattery bool) { - if !hasValue { - return - } - logger.Debug("property OnBattery changed to", onBattery) - m.PropsMu.Lock() - changed := m.setPropOnBattery(onBattery) - m.PropsMu.Unlock() - - if changed { - if onBattery { - playSound(soundutils.EventPowerUnplug) - } else { - playSound(soundutils.EventPowerPlug) - } - } - }) - - if err != nil { - logger.Warning(err) - } -} - -func (m *Manager) handleBeforeSuspend() { - m.setPrepareSuspend(suspendStatePrepare) - - // 检查屏幕保护状态(删除原有的运行状态获取逻辑,仅在未捕获时补充获取锁屏需求) - if !m.screensaverStateCaptured { - m.screensaverLockAtAwake = m.isScreensaverLockAtAwake() - } - logger.Debug("before sleep, screensaver running:", m.screensaverWasRunning, "lock at awake:", m.screensaverLockAtAwake) - - m.setDDEBlackScreenActive(true) - if m.UseWayland { - // 如果是treeland,并且待机休眠唤醒是需要解锁,则将session 给lock - if m.SleepLock { - err := m.currentSession.Lock(0) - if err != nil { - logger.Warning("set session lock failed:", err) - } - } - } - logger.Debug("before sleep") -} - -func (m *Manager) handleWakeup() { - m.setPrepareSuspend(suspendStateWakeup) - logger.Debug("wakeup") - - // 唤醒后还原捕获状态标志,避免影响后续逻辑 - m.screensaverStateCaptured = false - - // Fix wayland sometimes no dpms event after wakeup - if m.UseWayland { - err := m.service.Conn().Object("org.deepin.dde.KWayland1", - "/org/deepin/dde/KWayland1/Output").Call("org.deepin.dde.KWayland1.Idle.simulateUserActivity", 0).Err - - if err != nil { - logger.Warning(err) - } - } - - // 系统唤醒后重新处理关机定时器 - if m.ScheduledShutdownState { - m.scheduledShutdown(Init) - } - - m.delayInActive = true - time.AfterFunc(time.Duration(m.delayWakeupInterval)*time.Second, func() { - m.delayInActive = false - playSound(soundutils.EventWakeup) - - // 如果睡眠前屏幕保护正在运行且恢复时需要密码,唤醒时必须显示锁屏界面 - if m.screensaverWasRunning && m.screensaverLockAtAwake { - logger.Debug("wakeup: screensaver was running and lock at awake, show lock screen") - m.doLock(true) - } - - m.setDDEBlackScreenActive(false) - }) - - if v := m.submodules[submodulePSP]; v != nil { - if psp := v.(*powerSavePlan); psp != nil { - psp.HandleIdleOff() - } - } - - m.setDPMSModeOn() - err := m.display.RefreshBrightness(0) - if err != nil { - logger.Warning(err) - } - - ch := make(chan *dbus.Call, 1) - m.helper.Power.GoRefreshBatteries(0, ch) - go func() { - select { - case <-ch: - case <-time.After(2 * time.Second): - return - } - }() -} - -func (m *Manager) handleRefreshMains() { - logger.Debug("handleRefreshMains") - power := m.helper.Power - err := power.RefreshMains(0) - if err != nil { - logger.Warning(err) - } -} - -func (m *Manager) handleWakeupDDELowPowerCheck() { - power := m.helper.Power - hasBattery, err := power.HasBattery().Get(0) - if err != nil { - logger.Warning(err) - return - } - - logger.Info(" PrepareForSleep(False) : wakeup, hasBattery : ", hasBattery) - - if hasBattery { - // when wakeup update onBattery state - onBattery, err := power.OnBattery().Get(0) - if err != nil { - logger.Warning(err) - return - } - if onBattery != m.OnBattery { - m.setPropOnBattery(onBattery) - } - - // 使用电池 - if onBattery { - percentage, err := power.BatteryPercentage().Get(0) - if err != nil { - logger.Warning(err) - return - } - m.setPropBatteryPercentage(percentage) - - logger.Info(" PrepareForSleep(False) : wakeup, Battery percentage : ", percentage, m.BatteryPercentage[batteryDisplay], m.warnLevelConfig.ActionPercentage) - - if percentage <= float64(m.warnLevelConfig.ActionPercentage) { - return - } - } - - doCloseDDELowPower() - } -} - -func (m *Manager) handleBatteryDisplayUpdate() { - logger.Debug("handleBatteryDisplayUpdate") - power := m.helper.Power - hasBattery, err := power.HasBattery().Get(0) - if err != nil { - logger.Warning(err) - return - } - - m.PropsMu.Lock() - var warnLevelChanged bool - var warnLevel WarnLevel - - if hasBattery { - m.setPropBatteryIsPresent(true) - - percentage, err := power.BatteryPercentage().Get(0) - if err != nil { - logger.Warning(err) - } - m.setPropBatteryPercentage(percentage) - - timeToEmpty, err := power.BatteryTimeToEmpty().Get(0) - if err != nil { - logger.Warning(err) - } - - status, err := power.BatteryStatus().Get(0) - if err != nil { - logger.Warning(err) - } - m.setPropBatteryState(status) - - warnLevel = m.getWarnLevel(percentage, timeToEmpty) - // 当电池电量从1%->0%时,如果之前的warnLevel不为WarnLevelNone(电池的状态正常),此时不去做warnLevel改变处理 - // 防止某些机器在电量变为0时低电量屏保被取消,进入锁屏界面 - if m.warnLevelConfig.getWarnLevelConfig().UsePercentageForPolicy && percentage == 0.0 && m.WarnLevel != WarnLevelNone && m.OnBattery { - warnLevelChanged = false - } else { - warnLevelChanged = m.setPropWarnLevel(warnLevel) - } - } else { - warnLevel = WarnLevelNone - warnLevelChanged = m.setPropWarnLevel(WarnLevelNone) - delete(m.BatteryIsPresent, batteryDisplay) - delete(m.BatteryPercentage, batteryDisplay) - delete(m.BatteryState, batteryDisplay) - - err := m.service.EmitPropertiesChanged(m, nil, "BatteryIsPresent", - "BatteryPercentage", "BatteryState") - if err != nil { - logger.Warning(err) - } - } - - m.PropsMu.Unlock() - - if warnLevelChanged { - m.handleWarnLevelChanged(warnLevel) - } -} - -func (m *Manager) disableWarnLevelCountTicker() { - if m.warnLevelCountTicker != nil { - m.warnLevelCountTicker.Stop() - m.warnLevelCountTicker = nil - } -} - -func (m *Manager) handleWarnLevelChanged(level WarnLevel) { - logger.Debug("handleWarnLevelChanged") - m.disableWarnLevelCountTicker() - - switch level { - case WarnLevelAction: - if m.ScheduledShutdownState { - m.scheduledShutdown(Init) - } - playSound(soundutils.EventBatteryLow) - m.sendNotify(iconBatteryLow, "", - Tr("Battery critically low")) - - m.warnLevelCountTicker = newCountTicker(time.Second, func(count int) { - if count == 3 { - // after 3 seconds, lock and then show dde low power - if m.SleepLock { - m.lockWaitShow(5*time.Second, false) - } - } else if count == 4 { - doShowDDELowPower() - } else if count == 5 { - // after 5 seconds, force suspend - m.disableWarnLevelCountTicker() - - if m.LowPowerAction == lowPowerActionSuspend { - m.doSuspend() - } else { - m.doHibernate() - } - } - }) - - case WarnLevelCritical: - playSound(soundutils.EventBatteryLow) - m.sendNotify(iconBatteryLow, "", - Tr("Battery low, please plug in")) - - case WarnLevelDanger: - playSound(soundutils.EventBatteryLow) - m.sendNotify(iconBatteryLow, "", - Tr("Battery low, please plug in")) - - case WarnLevelLow: - playSound(soundutils.EventBatteryLow) - m.sendNotify(iconBatteryLow, "", - Tr("Battery low, please plug in")) - - case WarnLevelRemind: - playSound(soundutils.EventBatteryLow) - m.sendNotify(iconBatteryLow, "", - Tr("Battery low, please plug in")) - - case WarnLevelNone: - logger.Debug("Power sufficient") - doCloseDDELowPower() - if m.ScheduledShutdownState { - m.scheduledShutdown(Init) - } - // 由 低电量 到 电量充足,必然需要有线电源插入 - } -} diff --git a/session/power1/manager_stub.go b/session/power1/manager_stub.go deleted file mode 100644 index 332bd804b..000000000 --- a/session/power1/manager_stub.go +++ /dev/null @@ -1,62 +0,0 @@ -// SPDX-FileCopyrightText: 2018 - 2022 UnionTech Software Technology Co., Ltd. -// -// SPDX-License-Identifier: GPL-3.0-or-later - -package power - -import ( - "github.com/linuxdeepin/dde-api/powersupply/battery" -) - -const ( - dbusServiceName = "org.deepin.dde.Power1" - dbusPath = "/org/deepin/dde/Power1" - dbusInterface = dbusServiceName -) - -func (m *Manager) setPropBatteryIsPresent(val bool) { - old, exist := m.BatteryIsPresent[batteryDisplay] - if old != val || !exist { - m.BatteryIsPresent[batteryDisplay] = val - m.emitPropChangedBatteryIsPresent() - } -} - -func (m *Manager) emitPropChangedBatteryIsPresent() { - err := m.service.EmitPropertyChanged(m, "BatteryIsPresent", m.BatteryIsPresent) - if err != nil { - logger.Warning(err) - } -} - -func (m *Manager) setPropBatteryPercentage(val float64) { - logger.Debugf("set batteryDisplay percentage %.1f%%", val) - old, exist := m.BatteryPercentage[batteryDisplay] - if old != val || !exist { - m.BatteryPercentage[batteryDisplay] = val - m.emitPropChangedBatteryPercentage() - } -} - -func (m *Manager) emitPropChangedBatteryPercentage() { - err := m.service.EmitPropertyChanged(m, "BatteryPercentage", m.BatteryPercentage) - if err != nil { - logger.Warning(err) - } -} - -func (m *Manager) setPropBatteryState(val uint32) { - logger.Debug("set BatteryDisplay status", battery.Status(val), val) - old, exist := m.BatteryState[batteryDisplay] - if old != val || !exist { - m.BatteryState[batteryDisplay] = val - m.emitPropChangedBatteryState() - } -} - -func (m *Manager) emitPropChangedBatteryState() { - err := m.service.EmitPropertyChanged(m, "BatteryState", m.BatteryState) - if err != nil { - logger.Warning(err) - } -} diff --git a/session/power1/power_dbusutil.go b/session/power1/power_dbusutil.go deleted file mode 100644 index 485595ba0..000000000 --- a/session/power1/power_dbusutil.go +++ /dev/null @@ -1,380 +0,0 @@ -// Code generated by "dbusutil-gen -type Manager manager.go"; DO NOT EDIT. - -package power - -func (v *Manager) setPropScheduledShutdownState(value bool) (changed bool) { - if v.ScheduledShutdownState != value { - v.ScheduledShutdownState = value - v.emitPropChangedScheduledShutdownState(value) - return true - } - return false -} - -func (v *Manager) emitPropChangedScheduledShutdownState(value bool) error { - return v.service.EmitPropertyChanged(v, "ScheduledShutdownState", value) -} - -func (v *Manager) setPropShutdownTime(value string) (changed bool) { - if v.ShutdownTime != value { - v.ShutdownTime = value - v.emitPropChangedShutdownTime(value) - return true - } - return false -} - -func (v *Manager) emitPropChangedShutdownTime(value string) error { - return v.service.EmitPropertyChanged(v, "ShutdownTime", value) -} - -func (v *Manager) setPropShutdownRepetition(value int) (changed bool) { - if v.ShutdownRepetition != value { - v.ShutdownRepetition = value - v.emitPropChangedShutdownRepetition(value) - return true - } - return false -} - -func (v *Manager) emitPropChangedShutdownRepetition(value int) error { - return v.service.EmitPropertyChanged(v, "ShutdownRepetition", value) -} - -func (v *Manager) setPropCustomShutdownWeekDays(value []byte) (changed bool) { - if !byteSliceEqual(v.CustomShutdownWeekDays, value) { - v.CustomShutdownWeekDays = value - v.emitPropChangedCustomShutdownWeekDays(value) - return true - } - return false -} - -func (v *Manager) emitPropChangedCustomShutdownWeekDays(value []byte) error { - return v.service.EmitPropertyChanged(v, "CustomShutdownWeekDays", value) -} - -func (v *Manager) setPropLidIsPresent(value bool) (changed bool) { - if v.LidIsPresent != value { - v.LidIsPresent = value - v.emitPropChangedLidIsPresent(value) - return true - } - return false -} - -func (v *Manager) emitPropChangedLidIsPresent(value bool) error { - return v.service.EmitPropertyChanged(v, "LidIsPresent", value) -} - -func (v *Manager) setPropOnBattery(value bool) (changed bool) { - if v.OnBattery != value { - v.OnBattery = value - v.emitPropChangedOnBattery(value) - return true - } - return false -} - -func (v *Manager) emitPropChangedOnBattery(value bool) error { - return v.service.EmitPropertyChanged(v, "OnBattery", value) -} - -func (v *Manager) setPropUseWayland(value bool) (changed bool) { - if v.UseWayland != value { - v.UseWayland = value - v.emitPropChangedUseWayland(value) - return true - } - return false -} - -func (v *Manager) emitPropChangedUseWayland(value bool) error { - return v.service.EmitPropertyChanged(v, "UseWayland", value) -} - -func (v *Manager) setPropWarnLevel(value WarnLevel) (changed bool) { - if v.WarnLevel != value { - v.WarnLevel = value - v.emitPropChangedWarnLevel(value) - return true - } - return false -} - -func (v *Manager) emitPropChangedWarnLevel(value WarnLevel) error { - return v.service.EmitPropertyChanged(v, "WarnLevel", value) -} - -func (v *Manager) setPropLinePowerScreensaverDelay(value int) (changed bool) { - if v.LinePowerScreensaverDelay != value { - v.LinePowerScreensaverDelay = value - v.emitPropChangedLinePowerScreensaverDelay(value) - return true - } - return false -} - -func (v *Manager) emitPropChangedLinePowerScreensaverDelay(value int) error { - return v.service.EmitPropertyChanged(v, "LinePowerScreensaverDelay", value) -} - -func (v *Manager) setPropLinePowerScreenBlackDelay(value int) (changed bool) { - if v.LinePowerScreenBlackDelay != value { - v.LinePowerScreenBlackDelay = value - v.emitPropChangedLinePowerScreenBlackDelay(value) - return true - } - return false -} - -func (v *Manager) emitPropChangedLinePowerScreenBlackDelay(value int) error { - return v.service.EmitPropertyChanged(v, "LinePowerScreenBlackDelay", value) -} - -func (v *Manager) setPropLinePowerSleepDelay(value int) (changed bool) { - if v.LinePowerSleepDelay != value { - v.LinePowerSleepDelay = value - v.emitPropChangedLinePowerSleepDelay(value) - return true - } - return false -} - -func (v *Manager) emitPropChangedLinePowerSleepDelay(value int) error { - return v.service.EmitPropertyChanged(v, "LinePowerSleepDelay", value) -} - -func (v *Manager) setPropBatteryScreensaverDelay(value int) (changed bool) { - if v.BatteryScreensaverDelay != value { - v.BatteryScreensaverDelay = value - v.emitPropChangedBatteryScreensaverDelay(value) - return true - } - return false -} - -func (v *Manager) emitPropChangedBatteryScreensaverDelay(value int) error { - return v.service.EmitPropertyChanged(v, "BatteryScreensaverDelay", value) -} - -func (v *Manager) setPropBatteryScreenBlackDelay(value int) (changed bool) { - if v.BatteryScreenBlackDelay != value { - v.BatteryScreenBlackDelay = value - v.emitPropChangedBatteryScreenBlackDelay(value) - return true - } - return false -} - -func (v *Manager) emitPropChangedBatteryScreenBlackDelay(value int) error { - return v.service.EmitPropertyChanged(v, "BatteryScreenBlackDelay", value) -} - -func (v *Manager) setPropBatterySleepDelay(value int) (changed bool) { - if v.BatterySleepDelay != value { - v.BatterySleepDelay = value - v.emitPropChangedBatterySleepDelay(value) - return true - } - return false -} - -func (v *Manager) emitPropChangedBatterySleepDelay(value int) error { - return v.service.EmitPropertyChanged(v, "BatterySleepDelay", value) -} - -func (v *Manager) setPropScreenBlackLock(value bool) (changed bool) { - if v.ScreenBlackLock != value { - v.ScreenBlackLock = value - v.emitPropChangedScreenBlackLock(value) - return true - } - return false -} - -func (v *Manager) emitPropChangedScreenBlackLock(value bool) error { - return v.service.EmitPropertyChanged(v, "ScreenBlackLock", value) -} - -func (v *Manager) setPropSleepLock(value bool) (changed bool) { - if v.SleepLock != value { - v.SleepLock = value - v.emitPropChangedSleepLock(value) - return true - } - return false -} - -func (v *Manager) emitPropChangedSleepLock(value bool) error { - return v.service.EmitPropertyChanged(v, "SleepLock", value) -} - -func (v *Manager) setPropLinePowerLidClosedAction(value int32) (changed bool) { - if v.LinePowerLidClosedAction != value { - v.LinePowerLidClosedAction = value - v.emitPropChangedLinePowerLidClosedAction(value) - return true - } - return false -} - -func (v *Manager) emitPropChangedLinePowerLidClosedAction(value int32) error { - return v.service.EmitPropertyChanged(v, "LinePowerLidClosedAction", value) -} - -func (v *Manager) setPropLinePowerPressPowerBtnAction(value int32) (changed bool) { - if v.LinePowerPressPowerBtnAction != value { - v.LinePowerPressPowerBtnAction = value - v.emitPropChangedLinePowerPressPowerBtnAction(value) - return true - } - return false -} - -func (v *Manager) emitPropChangedLinePowerPressPowerBtnAction(value int32) error { - return v.service.EmitPropertyChanged(v, "LinePowerPressPowerBtnAction", value) -} - -func (v *Manager) setPropBatteryLidClosedAction(value int32) (changed bool) { - if v.BatteryLidClosedAction != value { - v.BatteryLidClosedAction = value - v.emitPropChangedBatteryLidClosedAction(value) - return true - } - return false -} - -func (v *Manager) emitPropChangedBatteryLidClosedAction(value int32) error { - return v.service.EmitPropertyChanged(v, "BatteryLidClosedAction", value) -} - -func (v *Manager) setPropBatteryPressPowerBtnAction(value int32) (changed bool) { - if v.BatteryPressPowerBtnAction != value { - v.BatteryPressPowerBtnAction = value - v.emitPropChangedBatteryPressPowerBtnAction(value) - return true - } - return false -} - -func (v *Manager) emitPropChangedBatteryPressPowerBtnAction(value int32) error { - return v.service.EmitPropertyChanged(v, "BatteryPressPowerBtnAction", value) -} - -func (v *Manager) setPropLinePowerLockDelay(value int) (changed bool) { - if v.LinePowerLockDelay != value { - v.LinePowerLockDelay = value - v.emitPropChangedLinePowerLockDelay(value) - return true - } - return false -} - -func (v *Manager) emitPropChangedLinePowerLockDelay(value int) error { - return v.service.EmitPropertyChanged(v, "LinePowerLockDelay", value) -} - -func (v *Manager) setPropBatteryLockDelay(value int) (changed bool) { - if v.BatteryLockDelay != value { - v.BatteryLockDelay = value - v.emitPropChangedBatteryLockDelay(value) - return true - } - return false -} - -func (v *Manager) emitPropChangedBatteryLockDelay(value int) error { - return v.service.EmitPropertyChanged(v, "BatteryLockDelay", value) -} - -func (v *Manager) setPropLowPowerNotifyEnable(value bool) (changed bool) { - if v.LowPowerNotifyEnable != value { - v.LowPowerNotifyEnable = value - v.emitPropChangedLowPowerNotifyEnable(value) - return true - } - return false -} - -func (v *Manager) emitPropChangedLowPowerNotifyEnable(value bool) error { - return v.service.EmitPropertyChanged(v, "LowPowerNotifyEnable", value) -} - -func (v *Manager) setPropLowPowerNotifyThreshold(value int32) (changed bool) { - if v.LowPowerNotifyThreshold != value { - v.LowPowerNotifyThreshold = value - v.emitPropChangedLowPowerNotifyThreshold(value) - return true - } - return false -} - -func (v *Manager) emitPropChangedLowPowerNotifyThreshold(value int32) error { - return v.service.EmitPropertyChanged(v, "LowPowerNotifyThreshold", value) -} - -func (v *Manager) setPropLowPowerAutoSleepThreshold(value int32) (changed bool) { - if v.LowPowerAutoSleepThreshold != value { - v.LowPowerAutoSleepThreshold = value - v.emitPropChangedLowPowerAutoSleepThreshold(value) - return true - } - return false -} - -func (v *Manager) emitPropChangedLowPowerAutoSleepThreshold(value int32) error { - return v.service.EmitPropertyChanged(v, "LowPowerAutoSleepThreshold", value) -} - -func (v *Manager) setPropLowPowerAction(value int32) (changed bool) { - if v.LowPowerAction != value { - v.LowPowerAction = value - v.emitPropChangedLowPowerAction(value) - return true - } - return false -} - -func (v *Manager) emitPropChangedLowPowerAction(value int32) error { - return v.service.EmitPropertyChanged(v, "LowPowerAction", value) -} - -func (v *Manager) setPropIsHighPerformanceSupported(value bool) (changed bool) { - if v.IsHighPerformanceSupported != value { - v.IsHighPerformanceSupported = value - v.emitPropChangedIsHighPerformanceSupported(value) - return true - } - return false -} - -func (v *Manager) emitPropChangedIsHighPerformanceSupported(value bool) error { - return v.service.EmitPropertyChanged(v, "IsHighPerformanceSupported", value) -} - -func (v *Manager) setPropLinePowerShortIdleDelay(value int) (changed bool) { - if v.LinePowerShortIdleDelay != value { - v.LinePowerShortIdleDelay = value - v.emitPropChangedLinePowerShortIdleDelay(value) - return true - } - return false -} - -func (v *Manager) emitPropChangedLinePowerShortIdleDelay(value int) error { - return v.service.EmitPropertyChanged(v, "LinePowerShortIdleDelay", value) -} - -func (v *Manager) setPropBatteryShortIdleDelay(value int) (changed bool) { - if v.BatteryShortIdleDelay != value { - v.BatteryShortIdleDelay = value - v.emitPropChangedBatteryShortIdleDelay(value) - return true - } - return false -} - -func (v *Manager) emitPropChangedBatteryShortIdleDelay(value int) error { - return v.service.EmitPropertyChanged(v, "BatteryShortIdleDelay", value) -} diff --git a/session/power1/power_save_plan.go b/session/power1/power_save_plan.go deleted file mode 100644 index 31ed46447..000000000 --- a/session/power1/power_save_plan.go +++ /dev/null @@ -1,1199 +0,0 @@ -// SPDX-FileCopyrightText: 2018 - 2026 UnionTech Software Technology Co., Ltd. -// -// SPDX-License-Identifier: GPL-3.0-or-later - -package power - -import ( - "context" - "errors" - "os" - "os/exec" - "strings" - "sync" - - "github.com/linuxdeepin/dde-daemon/common/fileutil" - "time" - - "github.com/godbus/dbus/v5" - ConfigManager "github.com/linuxdeepin/go-dbus-factory/org.desktopspec.ConfigManager" - "github.com/linuxdeepin/go-lib/dbusutil" - "github.com/linuxdeepin/go-lib/procfs" - x "github.com/linuxdeepin/go-x11-client" - xscreensaver "github.com/linuxdeepin/go-x11-client/ext/screensaver" - "github.com/linuxdeepin/go-x11-client/util/wm/ewmh" -) - -const submodulePSP = "PowerSavePlan" - -const ( - dsettingsAppID = "org.deepin.dde.daemon" - dsettingsPowerName = "org.deepin.dde.daemon.power" - dsettingsAllowScreenSaver = "allowScreenSaver" - dsettingsDelayWakeupInterval = "delayWakeupInterval" - dsettingsDelayHandleIdleOffIntervalWhenScreenBlack = "delayHandleIdleOffIntervalWhenScreenBlack" -) - -func init() { - submoduleList = append(submoduleList, newPowerSavePlan) -} - -type powerSavePlan struct { - systemSigLoop *dbusutil.SignalLoop - dsgPower ConfigManager.Manager - manager *Manager - screenSaverTimeout int32 - metaTasks metaTasks - tasks delayedTasks - // key output name, value old brightness - oldBrightnessTable map[string]float64 - mu sync.Mutex - screensaverRunning bool - - atomNetWMStateFullscreen x.Atom - atomNetWMStateFocused x.Atom - fullscreenWorkaroundAppList []string - - modeBeforeIdle string - allowScreenSaver bool - isIdle bool - shortIdleEnable bool - runningServicesMu sync.Mutex - runningServicesCache []string - runningServicesTime time.Time - runningServicesErr error - runningServicesErrTime time.Time -} - -func newPowerSavePlan(manager *Manager) (string, submodule, error) { - p := new(powerSavePlan) - p.manager = manager - - var err error - if !manager.UseWayland { - conn := manager.helper.xConn - p.atomNetWMStateFullscreen, err = conn.GetAtom("_NET_WM_STATE_FULLSCREEN") - if err != nil { - return submodulePSP, nil, err - } - p.atomNetWMStateFocused, err = conn.GetAtom("_NET_WM_STATE_FOCUSED") - if err != nil { - return submodulePSP, nil, err - } - } - - fullscreenWorkaroundAppListConfig, err := manager.dsPowerConfigManager.Value(0, dsettingFullscreenWorkaroundAppList) - if err != nil { - logger.Warning(err) - } else { - variantValue := fullscreenWorkaroundAppListConfig.Value() - if variants, ok := variantValue.([]dbus.Variant); ok { - p.fullscreenWorkaroundAppList = make([]string, len(variants)) - for i, v := range variants { - p.fullscreenWorkaroundAppList[i] = v.Value().(string) - } - } - } - - err = p.initDsgConfig() - if err != nil { - logger.Warning(err) - } - p.systemSigLoop.Start() - - return submodulePSP, p, nil -} - -// 监听 GSettings 值改变, 更新节电计划 -func (psp *powerSavePlan) initSettingsChangedHandler() { - m := psp.manager - m.dsPowerConfigManager.ConnectValueChanged(func(key string) { - logger.Debug("setting changed", key) - switch key { - case dsettingLinePowerScreensaverDelay, - dsettingLinePowerScreenBlackDelay, - dsettingLinePowerLockDelay, - dsettingLinePowerSleepDelay, - dsettingsLinePowerShortIdleDelay: - if !m.OnBattery { - logger.Debug("Change OnLinePower plan") - psp.OnLinePower() - } - - case dsettingBatteryScreensaverDelay, - dsettingBatteryScreenBlackDelay, - dsettingBatteryLockDelay, - dsettingBatterySleepDelay, - dsettingsBatteryShortIdleDelay: - if m.OnBattery { - logger.Debug("Change OnBattery plan") - psp.OnBattery() - } - - } - }) -} - -func (psp *powerSavePlan) OnBattery() { - logger.Debug("Use OnBattery plan") - m := psp.manager - psp.Update(int32(m.BatteryScreensaverDelay), int32(m.BatteryLockDelay), - int32(m.BatteryScreenBlackDelay), - int32(m.BatterySleepDelay), - int32(m.BatteryShortIdleDelay)) -} - -func (psp *powerSavePlan) OnLinePower() { - logger.Debug("Use OnLinePower plan") - m := psp.manager - psp.Update(int32(m.LinePowerScreensaverDelay), int32(m.LinePowerLockDelay), - int32(m.LinePowerScreenBlackDelay), - int32(m.LinePowerSleepDelay), - int32(m.LinePowerShortIdleDelay)) -} - -func (psp *powerSavePlan) Reset() { - m := psp.manager - logger.Debug("OnBattery:", m.OnBattery) - if m.OnBattery { - psp.OnBattery() - } else { - psp.OnLinePower() - } -} - - -func (psp *powerSavePlan) Start() error { - psp.Reset() - psp.initSettingsChangedHandler() - - helper := psp.manager.helper - power := helper.Power - screenSaver := helper.ScreenSaver - - // OnBattery changed will effect current PowerSavePlan - err := power.OnBattery().ConnectChanged(func(hasValue bool, value bool) { - psp.Reset() - }) - if err != nil { - logger.Warning("failed to connectChanged OnBattery:", err) - } - err = power.PowerSavingModeEnabled().ConnectChanged(psp.handlePowerSavingModeChanged) - if err != nil { - logger.Warning("failed to connectChanged PowerSavingModeEnabled:", err) - } - sessionType := os.Getenv("XDG_SESSION_TYPE") - if strings.Contains(sessionType, "wayland") { - err = psp.ConnectIdle() - if err != nil { - logger.Warning("failed to ConnectIdleOn:", err) - } - } else { - _, err = screenSaver.ConnectIdleOn(psp.HandleIdleOn) - if err != nil { - logger.Warning("failed to ConnectIdleOn:", err) - } - _, err = screenSaver.ConnectIdleOff(psp.HandleIdleOff) - if err != nil { - logger.Warning("failed to ConnectIdleOff:", err) - } - } - - psp.dealWithPowerSavingModeWhenSystemBoot() - return nil -} - -// 处理开关机前后,节能模式状态不一致的情况 -func (psp *powerSavePlan) dealWithPowerSavingModeWhenSystemBoot() { - power := psp.manager.helper.Power - newPowerSaveState, _ := power.PowerSavingModeEnabled().Get(0) - - powerSavingModeEnabled, err := psp.manager.dsPowerConfigManager.Value(0, dsettingsPowerSavingModeEnabled) - if err != nil { - logger.Warning(err) - return - } - if newPowerSaveState != powerSavingModeEnabled.Value().(bool) { - psp.handlePowerSavingModeChanged(true, newPowerSaveState) - } -} - -// 节能模式降低亮度比例变化。亮度缩放由 Display1 根据 Power1 的 PowerSavingModeBrightnessScale 属性处理, -// 节能模式变化后的处理。亮度缩放由 Display1 根据 Power1 的 PowerSavingModeBrightnessScale 属性处理, -// session/power1 不再直接修改亮度。 -func (psp *powerSavePlan) handlePowerSavingModeChanged(hasValue bool, enabled bool) { - if !hasValue { - return - } - logger.Debug("power saving mode enabled changed to", enabled) - psp.manager.setDsgData(dsettingsPowerSavingModeEnabled, enabled, psp.manager.dsPowerConfigManager) -} - -// 取消之前的任务 -func (psp *powerSavePlan) interruptTasks() { - psp.tasks.CancelAll() - psp.tasks.Wait(10*time.Millisecond, 200) - psp.tasks = nil -} - -func (psp *powerSavePlan) Destroy() { - psp.interruptTasks() -} - -func (psp *powerSavePlan) addTaskNoLock(t *delayedTask) { - psp.tasks = append(psp.tasks, t) -} - -func (psp *powerSavePlan) addTask(t *delayedTask) { - psp.mu.Lock() - psp.addTaskNoLock(t) - psp.mu.Unlock() -} - -type metaTask struct { - delay int32 - realDelay time.Duration - name string - fn func() -} - -type metaTasks []metaTask - -func (mts metaTasks) min() int32 { - if len(mts) == 0 { - return 0 - } - - min := mts[0].delay - for _, t := range mts[1:] { - if t.delay < min { - min = t.delay - } - } - return min -} - -func (mts metaTasks) setRealDelay(min int32) { - for idx := range mts { - t := &mts[idx] - nSecs := t.delay - min - if nSecs == 0 { - t.realDelay = 1 * time.Millisecond - } else { - t.realDelay = time.Second * time.Duration(nSecs) - } - } -} - -func (psp *powerSavePlan) Update(screenSaverStartDelay, lockDelay, - screenBlackDelay, sleepDelay, shortIdleDelay int32) { - psp.mu.Lock() - defer psp.mu.Unlock() - - psp.interruptTasks() - logger.Debugf("update(screenSaverStartDelay=%vs, lockDelay=%vs,"+ - " screenBlackDelay=%vs, sleepDelay=%vs, shortIdleDelay=%vs)", - screenSaverStartDelay, lockDelay, screenBlackDelay, sleepDelay, shortIdleDelay) - - // 按照优先级 待机=屏保>关闭显示器=自动锁屏 - tasks := make(metaTasks, 0, 5) - - if sleepDelay > 0 && canAddToTasks("sleep", sleepDelay, tasks) { - tasks = append(tasks, metaTask{ - name: "sleep", - delay: sleepDelay, - fn: psp.makeSystemSleep, - }) - } - if screenSaverStartDelay > 0 && canAddToTasks("screenSaverStart", screenSaverStartDelay, tasks) { - tasks = append(tasks, metaTask{ - name: "screenSaverStart", - delay: screenSaverStartDelay, - fn: psp.startScreensaver, - }) - } - - if lockDelay > 0 { - tasks = append(tasks, metaTask{ - name: "lock", - delay: lockDelay, - fn: psp.lock, - }) - } - - if screenBlackDelay > 0 { - tasks = append(tasks, metaTask{ - name: "screenBlack", - delay: screenBlackDelay, - fn: psp.screenBlack, - }) - } - - if shortIdleDelay > 0 { - tasks = append(tasks, metaTask{ - name: "shortIdleDelay", - delay: shortIdleDelay, - fn: psp.startShortIdleState, - }) - } - - min := tasks.min() - err := psp.setScreenSaverTimeout(min) - if err != nil { - logger.Warning("failed to set screen saver timeout:", err) - } - - psp.metaTasks = tasks - - if psp.isIdle { - logger.Info("System is already idle, restarting power delay tasks.") - psp.startIdleTasksLocked() - } else { - psp.metaTasks.setRealDelay(min) - } -} - -func (psp *powerSavePlan) setScreenSaverTimeout(seconds int32) error { - psp.screenSaverTimeout = seconds - logger.Debugf("set ScreenSaver timeout to %d", seconds) - err := psp.manager.helper.ScreenSaver.SetTimeout(0, uint32(seconds), 0, false) - if err != nil { - logger.Warningf("failed to set ScreenSaver timeout %d: %v", seconds, err) - } - return err -} - -func (psp *powerSavePlan) saveCurrentBrightness() error { - if psp.oldBrightnessTable == nil { - var err error - psp.oldBrightnessTable, err = psp.manager.helper.Display.Brightness().Get(0) - if err != nil { - return err - } - logger.Info("saveCurrentBrightness", psp.oldBrightnessTable) - return nil - } - - return errors.New("oldBrightnessTable is not nil") -} - -func (psp *powerSavePlan) resetBrightness() { - if psp.oldBrightnessTable != nil { - logger.Debug("Reset all outputs brightness") - psp.manager.setDisplayBrightness(psp.oldBrightnessTable) - psp.oldBrightnessTable = nil - } -} - -func (psp *powerSavePlan) startScreensaver() { - if os.Getenv("DESKTOP_CAN_SCREENSAVER") == "N" { - logger.Info("do not start screensaver, env DESKTOP_CAN_SCREENSAVER == N") - return - } - - if !psp.allowScreenSaver { - logger.Info("do not start screensaver, allowScreenSaver is false") - return - } - - startScreensaver() - psp.screensaverRunning = true -} - -func (psp *powerSavePlan) stopScreensaver() { - if !psp.screensaverRunning { - return - } - stopScreensaver() - psp.screensaverRunning = false -} - -func (psp *powerSavePlan) makeSystemSleep() { - logger.Info("sleep") - - if psp.manager.UseWayland { - psp.stopScreensaver() - psp.manager.doSuspend() - } else { - // 在停止屏幕保护前,统一捕获状态 - m := psp.manager - if m != nil { - m.captureScreensaverStateIfNeeded() - // 获取屏幕保护是否正在运行,仅在运行时才停止并标记 - running := m.isScreensaverRunning() - m.screensaverWasRunning = running - if running { - psp.stopScreensaver() - } - - // psp.manager.setDPMSModeOn() - // psp.resetBrightness() - m.doSuspendByFront() - } else { - logger.Warning("manager is nil") - } - } -} - -func (psp *powerSavePlan) lock() { - psp.manager.doLock(true) -} - -func (psp *powerSavePlan) getDesktopName(value string) (ret string) { - if !strings.Contains(value, "/") { - ret = value - return ret - } - parts := strings.Split(value, "/") - partsLength := len(parts) - if partsLength >= 1 { - ret = parts[partsLength-1] - } - return ret -} - -func getLaunchedApplications() []string { - bus, err := dbus.SessionBus() - if err != nil { - logger.Warning("getLaunchedApplications: failed to get session bus:", err) - return nil - } - - obj := bus.Object("org.desktopspec.ApplicationManager1", "/org/desktopspec/ApplicationManager1") - var result map[dbus.ObjectPath]map[string]map[string]dbus.Variant - err = obj.Call("org.desktopspec.DBus.ObjectManager.GetManagedObjects", 0).Store(&result) - if err != nil { - logger.Warning("getLaunchedApplications: failed to call GetManagedObjects:", err) - return nil - } - - var launched []string - for _, interfaces := range result { - appProps, ok := interfaces["org.desktopspec.ApplicationManager1.Application"] - if !ok { - continue - } - - instancesVariant, ok := appProps["Instances"] - if !ok { - continue - } - instances := instancesVariant.Value().([]dbus.ObjectPath) - if len(instances) == 0 { - continue - } - - desktopPathVariant, ok := appProps["DesktopSourcePath"] - if !ok { - continue - } - desktopPath := desktopPathVariant.Value().(string) - if desktopPath != "" { - launched = append(launched, desktopPath) - } - } - - return launched -} - -func interfaceToArrayString(v interface{}) (d []string) { - if v == nil { - return - } - - if d, ok := v.([]string); ok { - return d - } - - if variants, ok := v.([]dbus.Variant); ok { - d = make([]string, len(variants)) - for i, variant := range variants { - if str, ok := variant.Value().(string); ok { - d[i] = str - } else { - logger.Warningf("interfaceToArrayString: variant %d is not string: %#v", i, variant.Value()) - } - } - return d - } - - logger.Warningf("interfaceToArrayString() failed: unexpected type %T, value: %#v", v, v) - return -} - -func (psp *powerSavePlan) isThirdPartyAppRunning() (ret bool) { - launchedApplications := getLaunchedApplications() - logger.Info("launched applications: ", launchedApplications) - - if psp.manager == nil { - return - } - - systemApplicationsMap := psp.manager.systemApplicationsSnapshot() - shortIdleBlacklistApplicationsMap := psp.manager.shortIdleBlacklistApplicationsSnapshot() - logger.Debug("system applications: ", systemApplicationsMap) - - // 检查启动应用的desktop,是否在系统应用 systemApplicationsMap 中 - // 只要有一个运行中的desktop不存在于 systemApplicationsMap 中,说明就有第三方应用运行 - for _, app := range launchedApplications { - desktop := psp.getDesktopName(app) - // 如果存在短idle黑名单应用在运行,则返回true -> 不进短idle - if _, exists := shortIdleBlacklistApplicationsMap[desktop]; exists { - logger.Info("Found shortIdle blacklist application running: ", app, desktop) - ret = true - break - } - - if _, exists := systemApplicationsMap[desktop]; !exists { - desktop = strings.ToLower(desktop) - // 如果不存在的应用的desktop包含deepin、dde、uos说明也是系统应用,这个应用应该加到系统应用列表中 - if strings.Contains(desktop, "deepin") || strings.Contains(desktop, "dde") || strings.Contains(desktop, "uos") { - logger.Warning("Need add systemApplicationsMap, Running app : ", app, desktop) - continue - } - logger.Info("Found third-party application running: ", app, desktop) - ret = true - break - } - } - return ret -} - -func listRunningSystemServices() ([]string, error) { - ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) - defer cancel() - out, err := exec.CommandContext(ctx, "systemctl", "list-units", "--state=running", "--no-pager", "--no-legend", "--type=service").Output() - if err != nil { - logger.Warning("failed to list running services:", err) - return nil, err - } - - var runningServices []string - for _, line := range strings.Split(string(out), "\n") { - fields := strings.Fields(line) - if len(fields) == 0 { - continue - } - runningServices = append(runningServices, fields[0]) - } - logger.Debug("running services: ", runningServices) - return runningServices, nil -} - -func isSystemServiceName(name string) bool { - lowerName := strings.ToLower(name) - return strings.HasPrefix(lowerName, "dde-") || - strings.HasPrefix(lowerName, "deepin-") || - strings.HasPrefix(lowerName, "uos-") || - strings.HasPrefix(lowerName, "org.deepin.") || - strings.HasPrefix(lowerName, "com.deepin.") || - strings.HasPrefix(lowerName, "user@") -} - -func (psp *powerSavePlan) getRunningSystemServices() ([]string, error) { - psp.runningServicesMu.Lock() - defer psp.runningServicesMu.Unlock() - - if time.Since(psp.runningServicesTime) < 10*time.Second { - return append([]string(nil), psp.runningServicesCache...), nil - } - if psp.runningServicesErr != nil && time.Since(psp.runningServicesErrTime) < 5*time.Second { - return nil, psp.runningServicesErr - } - - runningServices, err := listRunningSystemServices() - if err != nil { - psp.runningServicesErr = err - psp.runningServicesErrTime = time.Now() - return nil, err - } - - psp.runningServicesCache = runningServices - psp.runningServicesTime = time.Now() - psp.runningServicesErr = nil - return append([]string(nil), psp.runningServicesCache...), nil -} - -func (psp *powerSavePlan) isThirdPartyServiceRunning() (ret bool) { - if psp.manager == nil { - return - } - - runningServices, err := psp.getRunningSystemServices() - if err != nil { - logger.Warning("failed to get running services, prevent short idle:", err) - return true - } - - systemServicesMap := psp.manager.systemServicesSnapshot() - - for _, name := range runningServices { - if _, exists := systemServicesMap[name]; !exists { - // 如果不存在的服务名带有系统服务前缀,该服务应该加到系统服务列表中 - if isSystemServiceName(name) { - logger.Debug("system Services, Running service: ", name) - continue - } - logger.Info("Found third-party service running: ", name) - ret = true - break - } - } - return ret -} - -func (psp *powerSavePlan) setDsg(key string, state bool) error { - if psp.dsgPower == nil { - return errors.New("dconfig interface dsgPower is nil") - } - - err := psp.dsgPower.SetValue(0, key, dbus.MakeVariant(state)) - if err != nil { - logger.Warning("setDsg failed : ", err) - } - return err -} - -// true: 进入短idle, false: 退出短idle -func (psp *powerSavePlan) changeShortIdleState(state bool) { - if !psp.shortIdleEnable { - logger.Info("short idle dsg of shortIdleEnable is close, not support.") - return - } - - if state { - if psp.isThirdPartyAppRunning() { - logger.Info("third-party application is running, Can't enter short idle.") - return - } - if psp.isThirdPartyServiceRunning() { - logger.Info("third-party service is running, Can't enter short idle.") - return - } - } - - psp.setDsg(dsettingsShortIdleState, state) - time.Sleep(300 * time.Millisecond) - callSetIdleState(state) -} - -// dde-system-daemon 写文件: /sys/devices/system/loongarch/relax_state -func callSetIdleState(state bool) { - systemConn, err := dbus.SystemBus() - if err != nil { - logger.Errorf("Failed to get system bus: %v", err) - return - } - - logger.Infof("callSetIdleState: calling SetIdleState with state=%v", state) - err = systemConn.Object("org.deepin.dde.Daemon1", "/org/deepin/dde/Daemon1").Call("org.deepin.dde.Daemon1.SetIdleState", 0, dbus.MakeVariant(state)).Err - if err != nil { - logger.Warning(err) - return - } - - logger.Infof("callSetIdleState: SetIdleState called successfully with state=%v", state) -} - -// dde-system-daemon 写文件: /sys/devices/system/loongarch/idle_state -func callSetScreenState(state bool) { - systemConn, err := dbus.SystemBus() - if err != nil { - logger.Errorf("Failed to get system bus: %v", err) - return - } - - logger.Infof("callSetScreenState: calling SetScreenState with state=%v", state) - err = systemConn.Object("org.deepin.dde.Daemon1", "/org/deepin/dde/Daemon1").Call("org.deepin.dde.Daemon1.SetScreenState", 0, dbus.MakeVariant(state)).Err - if err != nil { - logger.Warning(err) - return - } - - logger.Infof("callSetScreenState: SetScreenState called successfully with state=%v", state) -} - -func (psp *powerSavePlan) startShortIdleState() { - logger.Info("Start short idle state") - psp.changeShortIdleState(true) -} - -// 降低显示器亮度,最终关闭显示器 -func (psp *powerSavePlan) screenBlack() { - manager := psp.manager - logger.Info("Start screen black") - adjustBrightnessConfig, err := manager.dsPowerConfigManager.Value(0, dsettingAdjustBrightnessEnabled) - if err != nil { - logger.Warning(err) - return - } - - adjustBrightnessEnabled := adjustBrightnessConfig.Value().(bool) - - if adjustBrightnessEnabled { - err := psp.saveCurrentBrightness() - if err != nil { - adjustBrightnessEnabled = false - logger.Warning(err) - } else { - // half black - brightnessTable := make(map[string]float64) - brightnessRatio := 0.5 - logger.Debug("brightnessRatio:", brightnessRatio) - for output, oldBrightness := range psp.oldBrightnessTable { - brightnessTable[output] = oldBrightness * brightnessRatio - } - manager.setDisplayBrightness(brightnessTable) - } - } else { - logger.Debug("adjust brightness disabled") - } - - // full black - const fullBlackTime = 5000 * time.Millisecond - taskF := newDelayedTask("screenFullBlack", fullBlackTime, func() { - // 获取屏幕保护是否正在运行,仅在运行时才停止并标记 - running := manager.isScreensaverRunning() - manager.screensaverWasRunning = running - if running { - psp.stopScreensaver() - } - - logger.Info("Screen full black") - if adjustBrightnessEnabled { - // set min brightness for all outputs - brightnessTable := make(map[string]float64) - for output := range psp.oldBrightnessTable { - brightnessTable[output] = 0.02 - } - manager.setDisplayBrightness(brightnessTable) - } - manager.setDPMSModeOff() - if manager.ScreenBlackLock { - time.AfterFunc(200*time.Millisecond, func() { - manager.lockWaitShow(5*time.Second, true) - }) - } - - }) - psp.addTask(taskF) -} - -func (psp *powerSavePlan) shouldPreventIdle() (bool, error) { - conn := psp.manager.helper.xConn - activeWin, err := ewmh.GetActiveWindow(conn).Reply(conn) - if err != nil { - return false, err - } - - isFullscreenAndFocused, err := psp.isWindowFullScreenAndFocused(activeWin) - if err != nil { - return false, err - } - - if !isFullscreenAndFocused { - return false, nil - } - - pid, err := ewmh.GetWMPid(conn, activeWin).Reply(conn) - if err != nil { - return false, err - } - - p := procfs.Process(pid) - cmdline, err := p.Cmdline() - if err != nil { - return false, err - } - - for _, arg := range cmdline { - for _, app := range psp.fullscreenWorkaroundAppList { - if strings.Contains(arg, app) { - logger.Debugf("match %q", app) - return true, nil - } - } - } - return false, nil -} - -// 开始 Idle -func (psp *powerSavePlan) HandleIdleOn() { - psp.mu.Lock() - defer psp.mu.Unlock() - - if psp.manager.shouldIgnoreIdleOn() { - logger.Info("HandleIdleOn : IGNORE =========") - return - } - - if !psp.manager.isSessionActive() { - logger.Info("X11 session is inactive, don't HandleIdleOn") - return - } - - logger.Info("HandleIdleOn") - - psp.isIdle = true - psp.startIdleTasksLocked() -} - -func (psp *powerSavePlan) startIdleTasksLocked() { - // check window, only x11 is supported, not apply to wayland - if !psp.manager.UseWayland { - preventIdle, err := psp.shouldPreventIdle() - if err != nil { - logger.Warning(err) - } - if preventIdle { - logger.Debug("prevent idle") - err := psp.manager.helper.ScreenSaver.SimulateUserActivity(0) - if err != nil { - logger.Warning(err) - } - return - } - - idleTime := psp.metaTasks.min() - xConn := psp.manager.helper.xConn - xDefaultScreen := xConn.GetDefaultScreen() - if xDefaultScreen != nil { - xInfo, err := xscreensaver.QueryInfo(xConn, x.Drawable(xDefaultScreen.Root)).Reply(xConn) - if err == nil { - idleTime = int32(xInfo.MsSinceUserInput / 1000) - } else { - logger.Warning(err) - } - } else { - logger.Warning("cannot get X11 default screen") - } - - logger.Debugf("idle time: %d ms", idleTime) - psp.metaTasks.setRealDelay(idleTime) - } - psp.modeBeforeIdle, _ = psp.manager.helper.Power.Mode().Get(0) - - for _, t := range psp.metaTasks { - logger.Debugf("do %s after %v", t.name, t.realDelay) - task := newDelayedTask(t.name, t.realDelay, t.fn) - psp.addTaskNoLock(task) - } - - _, err := os.Stat("/etc/deepin/no_suspend") - if err == nil { - if psp.manager.ScreenBlackLock { - // m.setDPMSModeOn() - // m.lockWaitShow(4 * time.Second) - psp.manager.doLock(true) - time.Sleep(time.Millisecond * 500) - } - } -} - -func (ps *powerSavePlan) restoreDpmsStateFile() { - v, err := fileutil.SafeReadFile("/tmp/dpms-state") - if err != nil { - return - } - - if string(v) == "1" { - err = fileutil.SafeWriteFile("/tmp/dpms-state", []byte("0"), 0644) - if err != nil { - logger.Warning("write dpms state:", err) - } - } -} - -func (psp *powerSavePlan) handleIdleOff() { - psp.mu.Lock() - defer psp.mu.Unlock() - - psp.isIdle = false - psp.changeShortIdleState(false) - callSetScreenState(false) - - if psp.manager.shouldIgnoreIdleOff() { - psp.manager.setPrepareSuspend(suspendStateFinish) - logger.Info("HandleIdleOff : IGNORE =========") - return - } - - psp.modeBeforeIdle = "" - - psp.manager.setPrepareSuspend(suspendStateFinish) - logger.Info("HandleIdleOff") - psp.interruptTasks() - psp.manager.setDPMSModeOn() - psp.manager.setDDEBlackScreenActive(false) - psp.resetBrightness() - psp.restoreDpmsStateFile() -} - -// 结束 Idle -func (psp *powerSavePlan) HandleIdleOff() { - var powerPressAction int32 - if psp.manager.OnBattery { - powerPressAction = psp.manager.BatteryPressPowerBtnAction - } else { - powerPressAction = psp.manager.LinePowerPressPowerBtnAction - } - - if powerPressAction == powerActionTurnOffScreen { - var delayHandleIdleOffInterval uint32 - delayHandleIdleOffInterval = psp.manager.delayHandleIdleOffIntervalWhenScreenBlack - if delayHandleIdleOffInterval > 2500 { - // 当“按电源按钮时-关闭显示器”时,最长可增加2.5S延时 - delayHandleIdleOffInterval = 2500 - } - time.AfterFunc(time.Duration(delayHandleIdleOffInterval)*time.Millisecond, func() { - psp.handleIdleOff() - }) - return - } - - psp.handleIdleOff() -} - -func (psp *powerSavePlan) isWindowFullScreenAndFocused(xid x.Window) (bool, error) { - conn := psp.manager.helper.xConn - states, err := ewmh.GetWMState(conn, xid).Reply(conn) - if err != nil { - return false, err - } - found := 0 - for _, s := range states { - if s == psp.atomNetWMStateFullscreen { - found++ - } - // 后端的代码之前是基于deepin-wm这个窗口适配,现在换成了kwin,state中没有 focus 这个属性了 - // else if s == psp.atomNetWMStateFocused { - // found++ - // } - if found == 1 { - return true, nil - } - } - return false, nil -} - - -// 判断休眠、待机、屏保、锁屏、关闭显示器等任务能否加入任务队列 -// 优先级为:休眠 > 待机=屏保 > 锁屏=关闭显示器 -func canAddToTasks(sType string, delay int32, tasks metaTasks) bool { - if len(tasks) == 0 { - return true - } - - switch sType { - case "hibernate": - return true - case "sleep": - if delay < tasks.min() { - return true - } else { - return false - } - case "screenSaverStart": - if delay < tasks.min() { - return true - } else if delay == tasks.min() && tasks[len(tasks)-1].name == "sleep" { - return true - } else { - return false - } - - case "lock": - if delay < tasks.min() { - return true - } else { - return false - } - case "screenBlack": - if delay < tasks.min() { - return true - } else if delay == tasks.min() && tasks[len(tasks)-1].name == "lock" { - return true - } else { - return false - } - default: - return false - } -} - -func (psp *powerSavePlan) ConnectIdle() error { - sessionBus, err := dbus.SessionBus() - if err != nil { - logger.Warning(err) - return err - } - err = sessionBus.Object("org.deepin.dde.KWayland1", - "/org/deepin/dde/KWayland1/Output").AddMatchSignal("org.deepin.dde.KWayland1.Idle", "IdleTimeout").Err - if err != nil { - logger.Warning(err) - return err - } - sessionSigLoop := dbusutil.NewSignalLoop(sessionBus, 10) - sessionSigLoop.AddHandler(&dbusutil.SignalRule{ - Name: "org.deepin.dde.KWayland1.Idle.IdleTimeout", - }, func(sig *dbus.Signal) { - if strings.HasPrefix(string(sig.Path), - "/org/deepin/dde/KWayland1/") && - len(sig.Body) == 1 { - bIdle, ok := sig.Body[0].(bool) - if !ok { - return - } - if bIdle { - psp.HandleIdleOn() - } else { - psp.HandleIdleOff() - } - } - }) - sessionSigLoop.Start() - - return nil -} - -func (psp *powerSavePlan) initDsgConfig() error { - logger.Info("initDsgConfig.") - systemBus, err := dbus.SystemBus() - if err != nil { - return err - } - psp.systemSigLoop = dbusutil.NewSignalLoop(systemBus, 10) - // dsg 配置 - ds := ConfigManager.NewConfigManager(psp.systemSigLoop.Conn()) - dsPowerPath, err := ds.AcquireManager(0, dsettingsAppID, dsettingsPowerName, "") - if err != nil { - return err - } - dsPower, err := ConfigManager.NewManager(psp.systemSigLoop.Conn(), dsPowerPath) - if err != nil { - return err - } - psp.dsgPower = dsPower - - getAllowScreenSaver := func() { - data, err := dsPower.Value(0, dsettingsAllowScreenSaver) - if err != nil { - logger.Warning(err) - return - } - psp.allowScreenSaver = data.Value().(bool) - logger.Info("allow screen saver enabled : ", psp.allowScreenSaver) - } - - getAllowScreenSaver() - - getDelayWakeupInterval := func() { - v, err := dsPower.Value(0, dsettingsDelayWakeupInterval) - if err != nil { - logger.Warning(err) - return - } - switch vv := v.Value().(type) { - case float64: - psp.manager.delayWakeupInterval = uint32(vv) - case int64: - psp.manager.delayWakeupInterval = uint32(vv) - default: - logger.Warning("type is wrong!") - } - logger.Info("delay wake up interval : ", psp.manager.delayWakeupInterval) - } - - getDelayWakeupInterval() - - getDelayHandleIdleOffIntervalWhenScreenBlack := func() { - v, err := dsPower.Value(0, dsettingsDelayHandleIdleOffIntervalWhenScreenBlack) - if err != nil { - logger.Warning(err) - return - } - switch vv := v.Value().(type) { - case float64: - psp.manager.delayHandleIdleOffIntervalWhenScreenBlack = uint32(vv) - case int64: - psp.manager.delayHandleIdleOffIntervalWhenScreenBlack = uint32(vv) - default: - logger.Warning("type is wrong!") - } - logger.Info("delay wake up interval : ", psp.manager.delayHandleIdleOffIntervalWhenScreenBlack) - } - getDelayHandleIdleOffIntervalWhenScreenBlack() - - getSystemApplications := func() { - v, err := dsPower.Value(0, dsettingsSystemApplications) - if err != nil { - logger.Warning(err) - return - } - - dsgSystemApplications := interfaceToArrayString(v.Value()) - psp.manager.replaceSystemApplications(dsgSystemApplications, psp.getDesktopName) - logger.Info("system applications []string -> map : ", psp.manager.systemApplicationsSnapshot()) - } - getSystemApplications() - - getSystemServices := func() { - v, err := dsPower.Value(0, dsettingsSystemServices) - if err != nil { - logger.Warning(err) - return - } - dsgSystemServices := interfaceToArrayString(v.Value()) - psp.manager.replaceSystemServices(dsgSystemServices) - logger.Debug("system services []string -> map : ", psp.manager.systemServicesSnapshot()) - } - getSystemServices() - - getShortIdleEnable := func() { - data, err := dsPower.Value(0, dsettingsShortIdleEnable) - if err != nil { - logger.Warning(err) - return - } - psp.shortIdleEnable = data.Value().(bool) - logger.Info("dsg of shortIdleEnable : ", psp.shortIdleEnable) - } - getShortIdleEnable() - - getShortIdleBlacklistApplications := func() { - v, err := dsPower.Value(0, dsettingsShortIdleBlacklistApplications) - if err != nil { - logger.Warning(err) - return - } - - dsgShortIdleBlacklistApplications := interfaceToArrayString(v.Value()) - psp.manager.replaceShortIdleBlacklistApplications(dsgShortIdleBlacklistApplications, psp.getDesktopName) - logger.Info("shortIdle blackList system applications []string -> map : ", psp.manager.shortIdleBlacklistApplicationsSnapshot()) - } - getShortIdleBlacklistApplications() - - dsPower.InitSignalExt(psp.systemSigLoop, true) - dsPower.ConnectValueChanged(func(key string) { - logger.Info("DSG org.deepin.dde.daemon.power valueChanged, key : ", key) - switch key { - case dsettingsAllowScreenSaver: - getAllowScreenSaver() - case dsettingsDelayWakeupInterval: - getDelayWakeupInterval() - case dsettingsDelayHandleIdleOffIntervalWhenScreenBlack: - getDelayHandleIdleOffIntervalWhenScreenBlack() - case dsettingsSystemApplications: - getSystemApplications() - case dsettingsSystemServices: - getSystemServices() - case dsettingsShortIdleBlacklistApplications: - getShortIdleBlacklistApplications() - case dsettingsShortIdleEnable: - getShortIdleEnable() - default: - } - }) - - return nil -} diff --git a/session/power1/power_test.go b/session/power1/power_test.go deleted file mode 100644 index acfe5a961..000000000 --- a/session/power1/power_test.go +++ /dev/null @@ -1,194 +0,0 @@ -// SPDX-FileCopyrightText: 2018 - 2026 UnionTech Software Technology Co., Ltd. -// -// SPDX-License-Identifier: GPL-3.0-or-later - -package power - -import ( - "testing" - - "github.com/stretchr/testify/assert" -) - -func TestWarnLevelConfig(t *testing.T) { - conf := &warnLevelConfig{ - UsePercentageForPolicy: true, - - LowTime: 1200, - DangerTime: 900, - CriticalTime: 600, - ActionTime: 300, - - LowPowerNotifyThreshold: 20, - remindPercentage: 25, - LowPercentage: 20, - DangerPercentage: 15, - CriticalPercentage: 10, - ActionPercentage: 5, - } - assert.True(t, conf.isValid()) - conf.LowTime = 599 - assert.False(t, conf.isValid()) - - conf.LowTime = 1200 - conf.LowPercentage = 9 - assert.False(t, conf.isValid()) -} - -func Test_getWarnLevel(t *testing.T) { - config := &warnLevelConfig{ - UsePercentageForPolicy: true, - - LowTime: 1200, - DangerTime: 900, - CriticalTime: 600, - ActionTime: 300, - - LowPowerNotifyThreshold: 20, - remindPercentage: 25, - LowPercentage: 20, - DangerPercentage: 15, - CriticalPercentage: 10, - ActionPercentage: 5, - } - - onBattery := false - assert.Equal(t, getWarnLevel(config, onBattery, 1.0, 0), WarnLevelNone) - - onBattery = true - config.UsePercentageForPolicy = true - - assert.Equal(t, getWarnLevel(config, onBattery, 0.0, 0), WarnLevelNone) - assert.Equal(t, getWarnLevel(config, onBattery, 1.1, 0), WarnLevelAction) - assert.Equal(t, getWarnLevel(config, onBattery, 5.0, 0), WarnLevelAction) - assert.Equal(t, getWarnLevel(config, onBattery, 5.1, 0), WarnLevelCritical) - assert.Equal(t, getWarnLevel(config, onBattery, 10.0, 0), WarnLevelCritical) - assert.Equal(t, getWarnLevel(config, onBattery, 10.1, 0), WarnLevelDanger) - assert.Equal(t, getWarnLevel(config, onBattery, 15.0, 0), WarnLevelDanger) - assert.Equal(t, getWarnLevel(config, onBattery, 15.1, 0), WarnLevelLow) - assert.Equal(t, getWarnLevel(config, onBattery, 20.0, 0), WarnLevelLow) - assert.Equal(t, getWarnLevel(config, onBattery, 20.1, 0), WarnLevelNone) - assert.Equal(t, getWarnLevel(config, onBattery, 50.0, 0), WarnLevelNone) - - config.UsePercentageForPolicy = false - // use time to empty - assert.Equal(t, getWarnLevel(config, onBattery, 0, 0), WarnLevelNone) - assert.Equal(t, getWarnLevel(config, onBattery, 0, 61), WarnLevelAction) - assert.Equal(t, getWarnLevel(config, onBattery, 0, 300), WarnLevelAction) - assert.Equal(t, getWarnLevel(config, onBattery, 0, 301), WarnLevelCritical) - assert.Equal(t, getWarnLevel(config, onBattery, 0, 600), WarnLevelCritical) - assert.Equal(t, getWarnLevel(config, onBattery, 0, 601), WarnLevelDanger) - assert.Equal(t, getWarnLevel(config, onBattery, 0, 900), WarnLevelDanger) - assert.Equal(t, getWarnLevel(config, onBattery, 0, 901), WarnLevelLow) - assert.Equal(t, getWarnLevel(config, onBattery, 0, 1200), WarnLevelLow) - assert.Equal(t, getWarnLevel(config, onBattery, 0, 12001), WarnLevelNone) -} - -func TestManagerSystemApplicationsSnapshotReturnsCopy(t *testing.T) { - m := &Manager{ - systemApplicationsMap: map[string]string{"deepin-terminal.desktop": "/usr/share/applications/deepin-terminal.desktop"}, - } - - snapshot := m.systemApplicationsSnapshot() - snapshot["browser.desktop"] = "/usr/share/applications/browser.desktop" - - _, exists := m.systemApplicationsMap["browser.desktop"] - assert.False(t, exists) - assert.Equal(t, "/usr/share/applications/deepin-terminal.desktop", snapshot["deepin-terminal.desktop"]) -} - -func TestManagerReplaceSystemApplicationsReplacesContents(t *testing.T) { - m := &Manager{ - systemApplicationsMap: map[string]string{"old.desktop": "old.desktop"}, - } - psp := &powerSavePlan{manager: m} - - m.replaceSystemApplications([]string{"/usr/share/applications/deepin-terminal.desktop", "browser.desktop"}, psp.getDesktopName) - - assert.Equal(t, map[string]string{ - "deepin-terminal.desktop": "/usr/share/applications/deepin-terminal.desktop", - "browser.desktop": "browser.desktop", - }, m.systemApplicationsSnapshot()) -} - -func TestManagerShortIdleBlacklistSnapshotReturnsCopy(t *testing.T) { - m := &Manager{ - shortIdleBlackListApplicationsMap: map[string]string{"deepin-movie.desktop": "/usr/share/applications/deepin-movie.desktop"}, - } - - snapshot := m.shortIdleBlacklistApplicationsSnapshot() - snapshot["browser.desktop"] = "/usr/share/applications/browser.desktop" - - _, exists := m.shortIdleBlackListApplicationsMap["browser.desktop"] - assert.False(t, exists) - assert.Equal(t, "/usr/share/applications/deepin-movie.desktop", snapshot["deepin-movie.desktop"]) -} - -func TestManagerReplaceShortIdleBlacklistApplicationsReplacesContents(t *testing.T) { - m := &Manager{ - shortIdleBlackListApplicationsMap: map[string]string{"old.desktop": "old.desktop"}, - } - psp := &powerSavePlan{manager: m} - - m.replaceShortIdleBlacklistApplications([]string{"/usr/share/applications/deepin-movie.desktop", "browser.desktop"}, psp.getDesktopName) - - assert.Equal(t, map[string]string{ - "deepin-movie.desktop": "/usr/share/applications/deepin-movie.desktop", - "browser.desktop": "browser.desktop", - }, m.shortIdleBlacklistApplicationsSnapshot()) -} - -func TestManagerSystemServicesSnapshotReturnsCopy(t *testing.T) { - m := &Manager{ - systemServicesMap: map[string]string{"dde-session-daemon.service": "dde-session-daemon.service"}, - } - - snapshot := m.systemServicesSnapshot() - snapshot["custom.service"] = "custom.service" - - _, exists := m.systemServicesMap["custom.service"] - assert.False(t, exists) - assert.Equal(t, "dde-session-daemon.service", snapshot["dde-session-daemon.service"]) -} - -func TestManagerReplaceSystemServicesReplacesContents(t *testing.T) { - m := &Manager{ - systemServicesMap: map[string]string{"old.service": "old.service"}, - } - - m.replaceSystemServices([]string{"dde-session-daemon.service", "NetworkManager.service"}) - - assert.Equal(t, map[string]string{ - "dde-session-daemon.service": "dde-session-daemon.service", - "NetworkManager.service": "NetworkManager.service", - }, m.systemServicesSnapshot()) -} - -func TestMetaTasksMin(t *testing.T) { - tasks := metaTasks{ - metaTask{ - name: "n1", - delay: 10, - }, - metaTask{ - name: "n2", - delay: 30, - }, - metaTask{ - name: "n3", - delay: 20, - }, - } - assert.Equal(t, tasks.min(), int32(10)) - - tasks = metaTasks{} - assert.Equal(t, tasks.min(), int32(0)) - - tasks = metaTasks{ - metaTask{ - name: "n1", - delay: 10, - }, - } - assert.Equal(t, tasks.min(), int32(10)) -} diff --git a/session/power1/sleep_inhibit.go b/session/power1/sleep_inhibit.go deleted file mode 100644 index 9ccc42f8c..000000000 --- a/session/power1/sleep_inhibit.go +++ /dev/null @@ -1,164 +0,0 @@ -// SPDX-FileCopyrightText: 2018 - 2026 UnionTech Software Technology Co., Ltd. -// -// SPDX-License-Identifier: GPL-3.0-or-later - -package power - -import ( - "os" - "os/exec" - "syscall" - - "github.com/godbus/dbus/v5" - daemon "github.com/linuxdeepin/go-dbus-factory/system/org.deepin.dde.daemon1" - ofdbus "github.com/linuxdeepin/go-dbus-factory/system/org.freedesktop.dbus" - login1 "github.com/linuxdeepin/go-dbus-factory/system/org.freedesktop.login1" - "github.com/linuxdeepin/go-lib/dbusutil" -) - -const pipewireSuspendScript = "/usr/libexec/deepin/os-config/pipewire-suspend.sh" - -func runPipewireSuspendScriptIfExists(action string) bool { - if _, err := os.Stat(pipewireSuspendScript); err != nil { - return false - } - - err := exec.Command(pipewireSuspendScript, action).Run() - if err != nil { - logger.Warning("failed to run pipewire suspend script:", err) - return false - } - return true -} - -type sleepInhibitor struct { - loginManager login1.Manager - fd int - dbusObj ofdbus.DBus - sysLoop *dbusutil.SignalLoop - hasRunBeforeSleep bool - - OnWakeup func() - OnBeforeSuspend func() -} - -func newSleepInhibitor(login1Manager login1.Manager, daemon daemon.Daemon) *sleepInhibitor { - inhibitor := &sleepInhibitor{ - loginManager: login1Manager, - fd: -1, - } - systemBus, err := dbus.SystemBus() - if err != nil { - logger.Warning(err) - return nil - } - inhibitor.dbusObj = ofdbus.NewDBus(systemBus) - inhibitor.sysLoop = dbusutil.NewSignalLoop(systemBus, 10) - inhibitor.sysLoop.Start() - inhibitor.dbusObj.InitSignalExt(inhibitor.sysLoop, true) - _, err = daemon.ConnectHandleForSleep(func(before bool) { - logger.Info("sleepInhibitor HandleForSleep", before) - // signal `HandleForSleep` true -> false - if before { - _manager.PropsMu.Lock() - if !_manager.sessionActive { - logger.Debug("sessionActive is false,don't need run before sleep") - _manager.PropsMu.Unlock() - // 如果此用户此时不是活跃状态,则不处理待机唤醒信号. - return - } - _manager.PropsMu.Unlock() - - inhibitor.hasRunBeforeSleep = true - - // TODO: network prepare for sleep - // network.HandlePrepareForSleep(true) - if inhibitor.OnBeforeSuspend != nil { - inhibitor.OnBeforeSuspend() - } - if !runPipewireSuspendScriptIfExists("1") { - suspendPulseSinks(1) - suspendPulseSources(1) - } - err := inhibitor.unblock() - if err != nil { - logger.Warning(err) - } - } else { - if !inhibitor.hasRunBeforeSleep { - logger.Debug("not run before sleep,don't need run after sleep") - return - } - if !runPipewireSuspendScriptIfExists("0") { - suspendPulseSources(0) - suspendPulseSinks(0) - } - if inhibitor.OnWakeup != nil { - inhibitor.OnWakeup() - } - if _manager != nil { - _manager.handleRefreshMains() - _manager.handleBatteryDisplayUpdate() - _manager.handleWakeupDDELowPowerCheck() - } - //appearance.HandlePrepareForSleep(false) - err := inhibitor.block() - if err != nil { - logger.Warning(err) - } - inhibitor.hasRunBeforeSleep = false - } - }) - if err != nil { - logger.Warning(err) - } - return inhibitor -} - -func (inhibitor *sleepInhibitor) block() error { - logger.Debug("block sleep") - if inhibitor.fd != -1 { - return nil - } - inhibit := func() { - fd, err := inhibitor.loginManager.Inhibit(0, - "sleep", dbusServiceName, "run screen lock", "delay") - if err != nil { - logger.Warning(err) - return - } - inhibitor.fd = int(fd) - } - inhibit() - // handle login1 restart - _, _ = inhibitor.dbusObj.ConnectNameOwnerChanged(func(name string, oldOwner string, newOwner string) { - if name == "org.freedesktop.login1" && newOwner != "" && oldOwner == "" { - if inhibitor.fd != -1 { // 如果之前存在inhibit时,login1重启需要重新inhibit - err := syscall.Close(inhibitor.fd) - inhibitor.fd = -1 - if err != nil { - logger.Warning("failed to close fd:", err) - return - } - inhibit() - } - } - }) - // end handle login1 restart - return nil -} - -func (inhibitor *sleepInhibitor) unblock() error { - if inhibitor.fd == -1 { - return nil - } - logger.Debug("unblock sleep") - err := syscall.Close(inhibitor.fd) - inhibitor.fd = -1 - if err != nil { - logger.Warning("failed to close fd:", err) - return err - } - inhibitor.dbusObj.RemoveAllHandlers() - return nil -} diff --git a/session/power1/submodule.go b/session/power1/submodule.go deleted file mode 100644 index c40511061..000000000 --- a/session/power1/submodule.go +++ /dev/null @@ -1,59 +0,0 @@ -// SPDX-FileCopyrightText: 2018 - 2022 UnionTech Software Technology Co., Ltd. -// -// SPDX-License-Identifier: GPL-3.0-or-later - -package power - -import ( - "fmt" -) - -var submoduleList []func(*Manager) (string, submodule, error) - -type submodule interface { - Start() error - Destroy() -} - -func (m *Manager) initSubmodules() { - m.submodules = make(map[string]submodule, len(submoduleList)) - // new all submodule - for _, newMethod := range submoduleList { - name, submoduleInstance, err := newMethod(m) - logger.Debug("New submodule:", name) - if err != nil { - logger.Warningf("New submodule %v failed: %v", name, err) - continue - } - m.submodules[name] = submoduleInstance - } -} - -func (m *Manager) _startSubmodule(name string) error { - submodule, ok := m.submodules[name] - if !ok { - return fmt.Errorf("%v not exist", name) - } - return submodule.Start() -} - -func (m *Manager) startSubmodules() { - startOrder := []string{"PowerSavePlan", "LidSwitchHandler"} - for _, name := range startOrder { - logger.Infof("submodule %v start", name) - err := m._startSubmodule(name) - if err != nil { - logger.Warningf("submodule %v start failed: %v", name, err) - } - } -} - -func (m *Manager) destroySubmodules() { - if m.submodules != nil { - for name, submodule := range m.submodules { - logger.Debug("destroy submodule:", name) - submodule.Destroy() - } - m.submodules = nil - } -} diff --git a/session/power1/sync_config.go b/session/power1/sync_config.go deleted file mode 100644 index 2c2107657..000000000 --- a/session/power1/sync_config.go +++ /dev/null @@ -1,37 +0,0 @@ -// SPDX-FileCopyrightText: 2022 UnionTech Software Technology Co., Ltd. -// -// SPDX-License-Identifier: GPL-3.0-or-later - -package power - -import "encoding/json" - -type syncConfig struct { - m *Manager -} - -func (sc *syncConfig) Get() (interface{}, error) { - return &syncData{ - Version: "1.0", - ScreenBlackLock: sc.m.ScreenBlackLock, - SleepLock: sc.m.SleepLock, - }, nil -} - -func (sc *syncConfig) Set(data []byte) error { - var v syncData - err := json.Unmarshal(data, &v) - if err != nil { - return err - } - sc.m.ScreenBlackLock = v.ScreenBlackLock - sc.m.SleepLock = v.SleepLock - return nil -} - -// version: 1.0 -type syncData struct { - Version string `json:"version"` - ScreenBlackLock bool `json:"screen_black_lock"` - SleepLock bool `json:"sleep_lock"` -} diff --git a/session/power1/utils.go b/session/power1/utils.go deleted file mode 100644 index b8766274d..000000000 --- a/session/power1/utils.go +++ /dev/null @@ -1,772 +0,0 @@ -// SPDX-FileCopyrightText: 2018 - 2026 UnionTech Software Technology Co., Ltd. -// -// SPDX-License-Identifier: GPL-3.0-or-later - -package power - -import ( - "math" - "os/exec" - "strings" - "time" - - dbus "github.com/godbus/dbus/v5" - "github.com/linuxdeepin/dde-api/soundutils" - "github.com/linuxdeepin/dde-daemon/common/fileutil" - . "github.com/linuxdeepin/go-lib/gettext" - "github.com/linuxdeepin/go-lib/pulse" - "github.com/linuxdeepin/go-x11-client/ext/dpms" -) - -const ( - dpmsStateOn int32 = iota - dpmsStateStandBy - dpmsStateSuspend - dpmsStateOff -) - -func (m *Manager) waitLockShowing(timeout time.Duration) { - ticker := time.NewTicker(time.Millisecond * 300) - timer := time.NewTimer(timeout) - for { - select { - case _, ok := <-ticker.C: - if !ok { - logger.Error("Invalid ticker event") - return - } - - logger.Debug("waitLockShowing tick") - locked, err := m.helper.SessionManager.Locked().Get(0) - if err != nil { - logger.Warning(err) - continue - } - if locked { - logger.Debug("waitLockShowing found") - ticker.Stop() - return - } - - case <-timer.C: - logger.Debug("waitLockShowing failed timeout!") - ticker.Stop() - return - } - } -} - -func (m *Manager) lockWaitShow(timeout time.Duration, autoStartAuth bool) { - m.doLock(autoStartAuth) - if m.UseWayland { - logger.Debug("In wayland environment, unsupported check lock whether showin") - return - } - m.waitLockShowing(timeout) -} - -func (m *Manager) isWmBlackScreenActive() bool { - bus, err := dbus.SessionBus() - if err == nil { - kwinInter := bus.Object("org.kde.KWin", "/BlackScreen") - var active bool - err = kwinInter.Call("org.kde.kwin.BlackScreen.getActive", - dbus.FlagNoAutoStart).Store(&active) - if err != nil { - logger.Warning("failed to get kwin blackscreen effect active:", err) - return false - } - return active - } else { - return false - } -} - -func (m *Manager) setWmBlackScreenActive(active bool) { - if m.delayInActive { - return - } - - logger.Info("set blackScreen effect active: ", active) - bus, err := dbus.SessionBus() - if err == nil { - kwinInter := bus.Object("org.kde.KWin", "/BlackScreen") - err = kwinInter.Call("org.kde.kwin.BlackScreen.setActive", 0, active).Err - if err != nil { - logger.Warning("set blackScreen active failed:", err) - } - } -} - -func (m *Manager) setDDEBlackScreenActive(active bool) { - if m.delayInActive { - return - } - - if !m.SleepLock { - logger.Info("setDDEBlackScreenActive GSettings of sleep-lock is false, Not use dde black widget") - return - } - - logger.Info("set blackScreen effect active: ", active) - bus, err := dbus.SessionBus() - if err == nil { - dbusObject := bus.Object("org.deepin.dde.BlackScreen1", "/org/deepin/dde/BlackScreen1") - err = dbusObject.Call("org.deepin.dde.BlackScreen1.setActive", 0, active).Err - if err != nil { - logger.Warning("set blackScreen active failed:", err) - } - } - - blackscreenCmd := "dbus-send --print-reply --dest=org.kde.KWin /BlackScreen org.kde.kwin.BlackScreen.setActive boolean:" - if active { - blackscreenCmd = blackscreenCmd + "true" - } else { - blackscreenCmd = blackscreenCmd + "false" - } - cmd := exec.Command("/bin/bash", "-c", blackscreenCmd) - err = cmd.Run() - if err != nil { - logger.Warning("Set wm blackscreen failed", err) - } -} - -func (m *Manager) getDPMSMode() int32 { - logger.Debug("get DPMS Mode") - - var err error - var mode int32 - - if m.UseWayland { - mode, err = m.getDpmsModeByKwin() - } else { - var dpmsInfo *dpms.InfoReply - c := m.helper.xConn - dpmsInfo, err = dpms.Info(c).Reply(c) - if err != nil { - mode = int32(dpmsInfo.PowerLevel) - } - } - - if err != nil { - logger.Warning("get DPMS mode error:", err) - } - - return mode -} - -var prevTimestamp int64 - -func (m *Manager) setDPMSModeOn() { - if m.delayHandleIdleOffIntervalWhenScreenBlack == 0 { - timestamp := time.Now().UnixNano() - tmp := timestamp - prevTimestamp - logger.Debug("[setDPMSModeOn] timestamp:", prevTimestamp, timestamp, tmp) - prevTimestamp = timestamp - if tmp < 300000000 { - logger.Debug("[setDPMSModeOn] div < 300ms ignored.") - return - } - } - - logger.Info("DPMS On") - - autoWm := m.getAutoChangeDeepinWm() - if autoWm { - m.tryChangeDeepinWM() - } - - var err error - if m.UseWayland { - err = m.setDpmsModeByKwin(dpmsStateOn) - } else { - c := m.helper.xConn - err = dpms.ForceLevelChecked(c, dpms.DPMSModeOn).Check(c) - } - - if err != nil { - logger.Warning("set DPMS on error:", err) - } else { - callSetScreenState(false) - } - - if autoWm { - m.setAutoChangeDeepinWm(false) - } -} - -func (m *Manager) setDPMSModeOff() { - logger.Info("DPMS Off") - - var err error - if m.UseWayland { - err = m.setDpmsModeByKwin(dpmsStateOff) - } else { - c := m.helper.xConn - err = dpms.ForceLevelChecked(c, dpms.DPMSModeOff).Check(c) - } - if err != nil { - logger.Warning("set DPMS off error:", err) - } else { - callSetScreenState(true) - } - fileutil.SafeWriteFile("/tmp/dpms-state", []byte("1"), 0644) -} - -const ( - lockFrontServiceName = "org.deepin.dde.LockFront1" - lockFrontIfc = lockFrontServiceName - lockFrontObjPath = "/org/deepin/dde/LockFront1" -) - -func (m *Manager) tryChangeDeepinWM() bool { - ret := false - count := 0 - for { - if count > 2 { - break - } - count++ - - enabled, err := m.wmDBus.CompositingEnabled().Get(0) - if err != nil { - logger.Warning("tryChangeDeepinWM get CompositingEnabled err : ", err) - continue - } - if !enabled { - err := m.wmDBus.CompositingEnabled().Set(0, true) - if err != nil { - logger.Warning("tryChangeDeepinWM set CompositingEnabled true, err :", err) - continue - } - - // dde-osd需要使用该dconfig值,true不弹该特效osd - ret = true - break - } - } - - logger.Info(" tryChangeDeepinWM ret : ", ret) - return ret -} - -func (m *Manager) doLock(autoStartAuth bool) { - // 如果是treeland,直接执行login1 的session lock - if m.UseWayland { - err := m.currentSession.Lock(0) - if err != nil { - logger.Warning("set session lock failed:", err) - } - return - } - locked, err := m.sessionManager.Locked().Get(0) - if err != nil { - logger.Warning(err) - } - if locked { - logger.Info("Current is locked. ignore this doLock.") - return - } - - logger.Info("Lock Screen") - bus, err := dbus.SessionBus() - if err != nil { - logger.Warning(err) - return - } - lockFrontObj := bus.Object(lockFrontServiceName, lockFrontObjPath) - err = lockFrontObj.Call(lockFrontIfc+".ShowAuth", 0, autoStartAuth).Err - if err != nil { - logger.Warning("failed to call lockFront ShowAuth:", err) - } -} - -func (m *Manager) canSuspend() bool { - can, err := m.helper.SessionManager.CanSuspend(0) - if err != nil { - logger.Warning(err) - return false - } - return can -} - -func (m *Manager) doSuspend() { - if !m.canSuspend() { - logger.Info("can not suspend") - return - } - - logger.Debug("suspend") - m.captureScreensaverStateIfNeeded() - err := m.helper.SessionManager.RequestSuspend(0) - if err != nil { - logger.Warning("failed to suspend:", err) - } -} - -// 为了处理待机闪屏的问题,通过前端进行待机,前端会在待机前显示一个纯黑的界面 -func (m *Manager) doSuspendByFront() { - if !m.canSuspend() { - logger.Info("can not suspend") - return - } - - logger.Debug("suspend") - m.captureScreensaverStateIfNeeded() - err := m.helper.ShutdownFront.Suspend(0) - if err != nil { - logger.Warning("failed to suspend:", err) - } -} - -func (m *Manager) canShutdown() bool { - can, err := m.helper.SessionManager.CanShutdown(0) - if err != nil { - logger.Warning(err) - return false - } - return can -} - -// 正常关机流程,存在 block or delay shutdown 或多用户时,显示shutdown界面,其他情况,直接关机 -func (m *Manager) doShutdown() { - if m.hasShutdownInhibit() || m.hasMultipleDisplaySession() { - logger.Info("exist shutdown inhibit(delay or block) or multiple display session") - err := m.ddeShutdown.Shutdown(0) - if err != nil { - logger.Warning(err) - } - } else { - logger.Debug("Shutdown") - err := m.helper.SessionManager.RequestShutdown(0) - if err != nil { - logger.Warning("failed to Shutdown:", err) - } - } -} - -func (m *Manager) hasShutdownInhibit() bool { - // 先检查是否有delay 或 block shutdown的inhibitor - inhibitors, err := m.objLogin.ListInhibitors(0) - if err != nil { - logger.Warning("failed to call login ListInhibitors:", err) - } else { - for _, inhibit := range inhibitors { - logger.Infof("inhibit is: %+v", inhibit) - if strings.Contains(inhibit.What, "shutdown") { - return true - } - } - } - return false -} - -// 定时关机流程: 存在block关机项时,显示shutdown界面,无block时,直接关机,delay情况进行延迟关机 -func (m *Manager) doAutoShutdown() { - if m.hasShutdownBlock() { - logger.Warning("Shutdown") - err := m.ddeShutdown.Shutdown(0) - if err != nil { - logger.Warning(err) - } - } else { - logger.Warning("Shutdown") - err := m.helper.SessionManager.RequestShutdown(0) - // m.lastShutdownTime = time.Now().Unix() - // m.savePowerDsgConfig(dsettingLastShutdownTime) - if err != nil { - logger.Warning("failed to Shutdown:", err) - } - } -} - -func (m *Manager) hasShutdownBlock() bool { - // 检查是否有block shutdown的inhibitor - inhibitors, err := m.objLogin.ListInhibitors(0) - if err != nil { - logger.Warning("failed to call login ListInhibitors:", err) - } else { - for _, inhibit := range inhibitors { - logger.Infof("inhibit is: %+v", inhibit) - if strings.Contains(inhibit.What, "shutdown") && inhibit.Mode == "block" { - logger.Info("exist shutdown block") - return true - } - } - } - return false -} - -func (m *Manager) hasMultipleDisplaySession() bool { - // 检查是否有多个图形session,有多个图形session就需要显示阻塞界面 - sessions, err := m.displayManager.Sessions().Get(0) - if err != nil { - logger.Warning(err) - return false - } - return len(sessions) >= 2 -} - -func (m *Manager) canHibernate() bool { - can, err := m.helper.SessionManager.CanHibernate(0) - if err != nil { - logger.Warning(err) - return false - } - return can -} - -func (m *Manager) doHibernate() { - if !m.canHibernate() { - logger.Info("can not hibernate") - return - } - logger.Debug("hibernate") - err := m.helper.SessionManager.RequestHibernate(0) - if err != nil { - logger.Warning("failed to hibernate:", err) - } -} - -func (m *Manager) doHibernateByFront() { - if !m.canHibernate() { - logger.Info("can not hibernate") - return - } - - logger.Debug("hibernate") - err := m.helper.ShutdownFront.Hibernate(0) - if err != nil { - logger.Warning("failed to hibernate:", err) - } -} - -func (m *Manager) doTurnOffScreen() { - if m.ScreenBlackLock { - logger.Info("Show lock") - m.doLock(true) - time.Sleep(1 * time.Second) - } - - logger.Info("Turn off screen") - m.setDPMSModeOff() -} - -func (m *Manager) setDisplayBrightness(brightnessTable map[string]float64) { - display := m.helper.Display - for output, brightness := range brightnessTable { - logger.Infof("Change output %q brightness to %.2f", output, brightness) - err := display.SetBrightness(0, output, brightness) - if err != nil { - logger.Warningf("Change output %q brightness to %.2f failed: %v", output, brightness, err) - } else { - logger.Infof("Change output %q brightness to %.2f done!", output, brightness) - } - } -} - -func (m *Manager) setAndSaveDisplayBrightness(brightnessTable map[string]float64) { - display := m.helper.Display - for output, brightness := range brightnessTable { - logger.Infof("Change output %q brightness to %.2f", output, brightness) - err := display.SetAndSaveBrightness(0, output, brightness) - if err != nil { - logger.Warningf("Change output %q brightness to %.2f failed: %v", output, brightness, err) - } else { - logger.Infof("Change output %q brightness to %.2f done!", output, brightness) - } - } -} - -func doShowDDELowPower() { - logger.Info("Show dde low power") - go func() { - err := exec.Command(cmdDDELowPower, "--raise").Run() - if err != nil { - logger.Warning(err) - } - }() -} - -func doCloseDDELowPower() { - logger.Info("Close low power") - go func() { - err := exec.Command(cmdDDELowPower, "--quit").Run() - if err != nil { - logger.Warning(err) - } - }() -} - -func (m *Manager) sendNotify(icon, summary, body string) { - if !m.LowPowerNotifyEnable { - logger.Info("notify switch is off ") - return - } - n := m.helper.Notifications - _, err := n.Notify(0, "dde-control-center", 0, icon, summary, body, nil, nil, -1) - if err != nil { - logger.Warning(err) - } -} - -func (m *Manager) sendChangeNotify(icon, summary, body string) { - n := m.helper.Notifications - _, err := n.Notify(0, "dde-control-center", 0, icon, summary, body, nil, nil, -1) - if err != nil { - logger.Warning(err) - } -} - -const iconBatteryLow = "notification-battery-low" - -func playSound(name string) { - logger.Debug("play system sound", name) - go func() { - err := soundutils.PlaySystemSound(name, "") - if err != nil { - logger.Warning(err) - } - }() -} - -const ( - deepinScreensaverDBusServiceName = "com.deepin.ScreenSaver" - deepinScreensaverDBusPath = "/com/deepin/ScreenSaver" - deepinScreensaverDBusInterface = deepinScreensaverDBusServiceName -) - -// 通用的屏幕保护属性获取方法 -func (m *Manager) getScreensaverProperty(propertyName string) bool { - bus, err := dbus.SessionBus() - if err != nil { - logger.Warning("failed to get session bus:", err) - return false - } - - obj := bus.Object(deepinScreensaverDBusServiceName, deepinScreensaverDBusPath) - var variant dbus.Variant - err = obj.Call("org.freedesktop.DBus.Properties.Get", 0, deepinScreensaverDBusInterface, propertyName).Store(&variant) - if err != nil { - logger.Warning("failed to get screensaver "+propertyName+":", err) - return false - } - - if variant.Signature().String() != "b" { - logger.Warning("screensaver " + propertyName + " property is not boolean type") - return false - } - - return variant.Value().(bool) -} - -// 检查屏幕保护是否正在运行 -func (m *Manager) isScreensaverRunning() bool { - return m.getScreensaverProperty("isRunning") -} - -// 检查屏幕保护恢复时是否需要密码 -func (m *Manager) isScreensaverLockAtAwake() bool { - return m.getScreensaverProperty("lockScreenAtAwake") -} - -func startScreensaver() { - logger.Info("start screensaver") - bus, err := dbus.SessionBus() - if err != nil { - logger.Warning(err) - return - } - - obj := bus.Object(deepinScreensaverDBusServiceName, deepinScreensaverDBusPath) - err = obj.Call(deepinScreensaverDBusInterface+".Start", 0).Err - if err != nil { - logger.Warning(err) - } -} - -func stopScreensaver() { - logger.Info("stop screensaver") - bus, err := dbus.SessionBus() - if err != nil { - logger.Warning(err) - return - } - - obj := bus.Object(deepinScreensaverDBusServiceName, deepinScreensaverDBusPath) - err = obj.Call(deepinScreensaverDBusInterface+".Stop", 0).Err - if err != nil { - logger.Warning(err) - } -} - -// TODO(jouyouyun): move to common library -func suspendPulseSinks(suspend int) { - var ctx = pulse.GetContext() - if ctx == nil { - logger.Error("Failed to connect pulseaudio server") - return - } - for _, sink := range ctx.GetSinkList() { - ctx.SuspendSinkById(sink.Index, suspend) - } -} - -// TODO(jouyouyun): move to common library -func suspendPulseSources(suspend int) { - var ctx = pulse.GetContext() - if ctx == nil { - logger.Error("Failed to connect pulseaudio server") - return - } - for _, source := range ctx.GetSourceList() { - ctx.SuspendSourceById(source.Index, suspend) - } -} - -func (m *Manager) initDConfigConnectChanged() { - isIllegalAction := func(action int32) bool { - return (action == powerActionHibernate && !m.canHibernate()) || - (action == powerActionSuspend && !m.canSuspend()) - } - - // 监听 session power 的属性的改变,并发送通知 - m.dsPowerConfigManager.ConnectValueChanged(func(key string) { - logger.Debug("Power Settings Changed :", key) - switch key { - case dsettingLinePowerLidClosedAction: - value := m.LinePowerLidClosedAction - if isIllegalAction(value) { - break - } - case dsettingLinePowerPressPowerButton: - value := m.LinePowerPressPowerBtnAction - if isIllegalAction(value) { - break - } - case dsettingBatteryLidClosedAction: - value := m.BatteryLidClosedAction - if isIllegalAction(value) { - break - } - case dsettingBatteryPressPowerButton: - value := m.BatteryPressPowerBtnAction - if isIllegalAction(value) { - break - } - case dsettingHighPerformanceEnabled: - // 根据systemPower::IsHighPerformanceEnabled GSetting::settingKeyHighPerformanceEnabled - highPerformanceEnabled, err := m.dsPowerConfigManager.Value(0, dsettingHighPerformanceEnabled) - if err != nil { - logger.Warning(err) - return - } - bSettingKeyHighPerformanceEnabled := highPerformanceEnabled.Value().(bool) - if bSettingKeyHighPerformanceEnabled == m.gsHighPerformanceEnabled { - return - } - m.gsHighPerformanceEnabled = bSettingKeyHighPerformanceEnabled - isHighPerformanceSupported, _ := m.systemPower.IsHighPerformanceSupported().Get(0) - m.setPropIsHighPerformanceSupported(isHighPerformanceSupported && bSettingKeyHighPerformanceEnabled) - } - }) -} - -func getPowerActionString(action int32) string { - switch action { - case powerActionShutdown: - return Tr("your computer will shut down") - case powerActionSuspend: - return Tr("your computer will suspend") - case powerActionHibernate: - return Tr("your computer will hibernate") - case powerActionTurnOffScreen: - return Tr("your monitor will turn off") - case powerActionShowShutdownInterface: - return Tr("your monitor will show the shutdown interface") - case powerActionDoNothing: - return Tr("it will do nothing to your computer") - } - return "" -} - -func isFloatEqual(f1, f2 float64) bool { - return math.Abs(f1-f2) < 1e-6 -} - -func (m *Manager) getDpmsList() ([]dbus.Variant, error) { - sessionBus := m.sessionSigLoop.Conn() - sessionObj := sessionBus.Object("org.deepin.dde.KWayland1", "/org/deepin/dde/KWayland1/DpmsManager") - var ret []dbus.Variant - err := sessionObj.Call("org.deepin.dde.KWayland1.DpmsManager.dpmsList", 0).Store(&ret) - if err != nil { - logger.Warning(err) - return nil, err - } - - return ret, nil -} - -func (m *Manager) getDpmsModeByKwin() (int32, error) { - list, err := m.getDpmsList() - if err != nil { - logger.Warning(err) - return dpmsStateOn, err - } - - var dpmsMode int32 - for i := 0; i < len(list); i++ { - v := list[i].Value().(string) - sessionObj := m.sessionSigLoop.Conn().Object("org.deepin.dde.KWayland1", dbus.ObjectPath(v)) - err = sessionObj.Call("org.deepin.dde.KWayland1.Dpms.getDpmsMode", 0).Store(&dpmsMode) - if err != nil { - logger.Warning(err) - return dpmsStateOn, err - } - } - - return dpmsMode, nil -} - -func (m *Manager) setDpmsModeByKwin(mode int32) error { - list, err := m.getDpmsList() - if err != nil { - logger.Warning(err) - return err - } - - for i := 0; i < len(list); i++ { - v := list[i].Value().(string) - sessionObj := m.sessionSigLoop.Conn().Object("org.deepin.dde.KWayland1", dbus.ObjectPath(v)) - err = sessionObj.Call("org.deepin.dde.KWayland1.Dpms.setDpmsMode", 0, int32(mode)).Err - if err != nil { - logger.Warning(err) - return err - } - } - - return nil -} - -func byteSliceEqual(v1, v2 []byte) bool { - if len(v1) != len(v2) { - return false - } - for i, e1 := range v1 { - if e1 != v2[i] { - return false - } - } - return true -} - -func (m *Manager) captureScreensaverStateIfNeeded() { - if m == nil || m.screensaverStateCaptured { - return - } - - // 仅捕获恢复是否需要密码;是否“正在运行”由停止屏保前的路径设置 - m.screensaverLockAtAwake = m.isScreensaverLockAtAwake() - m.screensaverStateCaptured = true - logger.Debug("capture screensaver lockAtAwake=", m.screensaverLockAtAwake) -} diff --git a/session/power1/warn_level.go b/session/power1/warn_level.go deleted file mode 100644 index 675dbfe8d..000000000 --- a/session/power1/warn_level.go +++ /dev/null @@ -1,97 +0,0 @@ -// SPDX-FileCopyrightText: 2018 - 2022 UnionTech Software Technology Co., Ltd. -// -// SPDX-License-Identifier: GPL-3.0-or-later - -package power - -type WarnLevel uint32 - -const ( - WarnLevelNone WarnLevel = iota - WarnLevelRemind - WarnLevelLow - WarnLevelDanger - WarnLevelCritical - WarnLevelAction -) - -func (lv WarnLevel) String() string { - switch lv { - case WarnLevelNone: - return "None" - case WarnLevelRemind: - return "Remind" - case WarnLevelLow: - return "Low" - case WarnLevelDanger: - return "Danger" - case WarnLevelCritical: - return "Critical" - case WarnLevelAction: - return "Action" - default: - return "Unknown" - } -} - -func getWarnLevel(config *warnLevelConfig, onBattery bool, - percentage float64, timeToEmpty uint64) WarnLevel { // 低电量的处理 - - if !onBattery { - return WarnLevelNone - } - - usePercentageForPolicy := config.UsePercentageForPolicy - logger.Debugf("_getWarnLevel onBattery %v, percentage %v, timeToEmpty %v, usePercentage %v", - onBattery, percentage, timeToEmpty, usePercentageForPolicy) - if usePercentageForPolicy { - // 电源管理模块异常时获取到百分比会一直为0,此时设置告警等级为WarnLevelNone - if percentage == 0.0 { - return WarnLevelNone - } - // 当电池电量到达低电量阈值且达到系统固定低电量提醒值时,才去弹低电量提醒通知 - if percentage <= config.LowPowerNotifyThreshold { - if percentage <= config.ActionPercentage { - return WarnLevelAction - } - - if percentage <= config.CriticalPercentage { - return WarnLevelCritical - } - - if percentage <= config.DangerPercentage { - return WarnLevelDanger - } - - if percentage <= config.LowPercentage { - return WarnLevelLow - } - - if percentage <= config.remindPercentage { - return WarnLevelRemind - } - - return WarnLevelNone - } - - return WarnLevelNone - } else { - if timeToEmpty > config.LowTime || timeToEmpty == 0 { - return WarnLevelNone - } - if timeToEmpty > config.DangerTime { - return WarnLevelLow - } - if timeToEmpty > config.CriticalTime { - return WarnLevelDanger - } - if timeToEmpty > config.ActionTime { - return WarnLevelCritical - } - return WarnLevelAction - } -} - -func (m *Manager) getWarnLevel(percentage float64, timeToEmpty uint64) WarnLevel { - return getWarnLevel(m.warnLevelConfig.getWarnLevelConfig(), m.OnBattery, percentage, timeToEmpty) -} diff --git a/session/power1/warn_level_config.go b/session/power1/warn_level_config.go deleted file mode 100644 index be42485c9..000000000 --- a/session/power1/warn_level_config.go +++ /dev/null @@ -1,195 +0,0 @@ -// SPDX-FileCopyrightText: 2018 - 2022 UnionTech Software Technology Co., Ltd. -// -// SPDX-License-Identifier: GPL-3.0-or-later - -package power - -import ( - "time" - - dbus "github.com/godbus/dbus/v5" -) - -type warnLevelConfig struct { - UsePercentageForPolicy bool - LowTime uint64 - DangerTime uint64 - CriticalTime uint64 - ActionTime uint64 - LowPowerNotifyThreshold float64 - remindPercentage float64 // 废弃 - LowPercentage float64 // 废弃 - DangerPercentage float64 // 废弃 - CriticalPercentage float64 // 废弃 - ActionPercentage float64 -} - -func (c *warnLevelConfig) isValid() bool { - if c.LowTime > c.DangerTime && - c.DangerTime > c.CriticalTime && - c.CriticalTime > c.ActionTime && - c.remindPercentage > c.LowPercentage && - c.LowPercentage > c.DangerPercentage && - c.DangerPercentage > c.CriticalPercentage && - c.CriticalPercentage > c.ActionPercentage { - return true - } - return false -} - -type WarnLevelConfigManager struct { - UsePercentageForPolicy bool `prop:"access:rw"` - - LowTime int64 `prop:"access:rw"` - DangerTime int64 `prop:"access:rw"` - CriticalTime int64 `prop:"access:rw"` - ActionTime int64 `prop:"access:rw"` - - LowPowerNotifyThreshold int64 `prop:"access:rw"` - - ActionPercentage int64 `prop:"access:rw"` - - changeTimer *time.Timer - changeCb func() - - powerManager *Manager -} - -func NewWarnLevelConfigManager(manager *Manager) *WarnLevelConfigManager { - m := &WarnLevelConfigManager{} - m.powerManager = manager - return m -} - -func (m *WarnLevelConfigManager) initDsg() { - needUpdateConfigKeys := []string{ - dsettingUsePercentageForPolicy, - dsettingTimeToEmptyLow, - dsettingTimeToEmptyDanger, - dsettingTimeToEmptyCritical, - dsettingTimeToEmptyAction, - dsettingPercentageAction, - dsettingLowPowerNotifyThreshold, - } - for _, key := range needUpdateConfigKeys { - m.getConfig(key) - } - - m.powerManager.dsPowerConfigManager.ConnectValueChanged(func(key string) { - m.getConfig(key) - m.notifyChange() - }) -} - -func (m *WarnLevelConfigManager) getConfig(key string) { - data, err := m.powerManager.dsPowerConfigManager.Value(0, key) - - if err != nil { - logger.Warning(err) - return - } - - switch key { - case dsettingUsePercentageForPolicy: - m.UsePercentageForPolicy = data.Value().(bool) - case dsettingTimeToEmptyLow: - m.LowTime = data.Value().(int64) - case dsettingTimeToEmptyDanger: - m.DangerTime = data.Value().(int64) - case dsettingTimeToEmptyCritical: - m.CriticalTime = data.Value().(int64) - case dsettingTimeToEmptyAction: - m.ActionTime = data.Value().(int64) - case dsettingLowPowerNotifyThreshold: - m.LowPowerNotifyThreshold = data.Value().(int64) - case dsettingPercentageAction: - m.ActionPercentage = data.Value().(int64) - } -} - -func (m *WarnLevelConfigManager) getWarnLevelConfig() *warnLevelConfig { - return &warnLevelConfig{ - UsePercentageForPolicy: m.UsePercentageForPolicy, - LowTime: uint64(m.LowTime), - DangerTime: uint64(m.DangerTime), - CriticalTime: uint64(m.CriticalTime), - ActionTime: uint64(m.ActionTime), - - LowPowerNotifyThreshold: float64(m.LowPowerNotifyThreshold), - remindPercentage: float64(25), - LowPercentage: float64(20), - DangerPercentage: float64(15), - CriticalPercentage: float64(10), - ActionPercentage: float64(m.ActionPercentage), - } -} - -func (m *WarnLevelConfigManager) setChangeCallback(fn func()) { - m.changeCb = fn -} - -func (m *WarnLevelConfigManager) delayCheckValid() { - logger.Debug("delayCheckValid") - if m.changeTimer != nil { - m.changeTimer.Stop() - } - m.changeTimer = time.AfterFunc(20*time.Second, func() { - logger.Debug("checkValid") - wlc := m.getWarnLevelConfig() - if !wlc.isValid() { - logger.Info("Warn level config is invalid, reset") - err := m.Reset() - if err != nil { - logger.Warning(err) - } - } - }) -} - -func (m *WarnLevelConfigManager) notifyChange() { - if m.changeCb != nil { - logger.Debug("WarnLevelConfig change") - m.changeCb() - } - m.delayCheckValid() -} - -func (m *WarnLevelConfigManager) connectSettingsChanged() { - m.powerManager.dsPowerConfigManager.ConnectValueChanged(func(key string) { - switch key { - case dsettingUsePercentageForPolicy, - dsettingLowPowerNotifyThreshold, - dsettingPercentageAction, - dsettingTimeToEmptyLow, - dsettingTimeToEmptyDanger, - dsettingTimeToEmptyCritical, - dsettingTimeToEmptyAction: - - logger.Debug("key changed", key) - m.notifyChange() - } - }) - -} - -func (m *WarnLevelConfigManager) Reset() *dbus.Error { - needResetConfigKeys := []string{ - dsettingUsePercentageForPolicy, - dsettingLowPowerNotifyThreshold, - dsettingPercentageAction, - dsettingTimeToEmptyLow, - dsettingTimeToEmptyDanger, - dsettingTimeToEmptyCritical, - dsettingTimeToEmptyAction, - } - - for _, key := range needResetConfigKeys { - m.powerManager.dsPowerConfigManager.Reset(0, key) - } - - return nil -} - -func (*WarnLevelConfigManager) GetInterfaceName() string { - return dbusInterface + ".WarnLevelConfig" -} diff --git a/system/power1/battery.go b/system/power1/battery.go deleted file mode 100644 index ba5fbfaa9..000000000 --- a/system/power1/battery.go +++ /dev/null @@ -1,277 +0,0 @@ -// SPDX-FileCopyrightText: 2018 - 2022 UnionTech Software Technology Co., Ltd. -// -// SPDX-License-Identifier: GPL-3.0-or-later - -package power - -import ( - "path/filepath" - "strings" - "sync" - "time" - - dbus "github.com/godbus/dbus/v5" - "github.com/linuxdeepin/dde-api/powersupply/battery" - gudev "github.com/linuxdeepin/go-gir/gudev-1.0" - "github.com/linuxdeepin/go-lib/dbusutil" -) - -type Battery struct { - service *dbusutil.Service - exit chan struct{} - - gudevClient *gudev.Client - - PropsMu sync.RWMutex - SysfsPath string - IsPresent bool - - Manufacturer string - ModelName string - SerialNumber string - Name string - Technology string - - Energy float64 - EnergyFull float64 - EnergyFullDesign float64 - EnergyRate float64 - - Voltage float64 - Percentage float64 - Capacity float64 - Status battery.Status - TimeToEmpty uint64 - TimeToFull uint64 - UpdateTime int64 - - batteryHistory []float64 - - refreshDone func() -} - -const ( - checkTimeSliceCount = 2 - checkTimeFloatRange = 120 -) - -func newBattery(manager *Manager, device *gudev.Device) *Battery { - sysfsPath := device.GetSysfsPath() - logger.Debugf("NewBattery sysfsPath: %q", sysfsPath) - if manager == nil || manager.gudevClient == nil || - device == nil { - return nil - } - bat := &Battery{ - service: manager.service, - gudevClient: manager.gudevClient, - SysfsPath: sysfsPath, - } - ok := bat.refresh(device) - if !ok { - return nil - } - bat.resetUpdateInterval(60 * time.Second) - return bat -} - -const ( - batteryDBusInterface = dbusInterface + ".Battery" -) - -func (*Battery) GetInterfaceName() string { - return batteryDBusInterface -} - -func (bat *Battery) getObjPath() dbus.ObjectPath { - return dbus.ObjectPath(dbusPath + "/battery_" + getValidName(filepath.Base(bat.SysfsPath))) -} - -func getValidName(n string) string { - // dbus objpath 0-9 a-z A-Z _ - n = strings.Replace(n, "-", "_x0", -1) - n = strings.Replace(n, ".", "_x1", -1) - n = strings.Replace(n, ":", "_x2", -1) - return n -} - -func checkTimeStabilized(s []uint64, t uint64) bool { - if len(s) <= checkTimeSliceCount { - // 记录少于 3 - return false - } - - // 循环最后三次记录 - length := len(s) - for i := 1; i <= checkTimeSliceCount; i++ { - if t+checkTimeFloatRange <= s[length-i] { - // 所处记录大于 t+允许浮动值 - return false - } - if t-checkTimeFloatRange >= s[length-i] { - // 所处记录小于 t-允许浮动值 - return false - } - } - - return true -} - -func (bat *Battery) setRefreshDoneCallback(fn func()) { - bat.refreshDone = fn -} - -func (bat *Battery) newDevice() *gudev.Device { - return bat.gudevClient.QueryBySysfsPath(bat.SysfsPath) -} - -func (bat *Battery) refresh(dev *gudev.Device) (ok bool) { - endDelay := bat.service.DelayEmitPropertyChanged(bat) - batInfo := battery.GetBatteryInfo(dev) - if batInfo == nil { - if endDelay != nil { - err := endDelay() - if err != nil { - logger.Warning(err) - } - } - return - } - - setTimeToFull := true - if batInfo.Status == battery.StatusCharging { - /* - * bug: https://pms.uniontech.com/zentao/bug-view-15187.html - * \desc Because the time to full provide by Upower module is not stable - * when just started charging. There are now two way solve that: - * 1. take the average value of the times, but the frequency of refresh battry is 60 seconds. - * If add more time tickers may introducing new bugs because the refresh() method can used by - * other method. Just like: https://pms.uniontech.com/zentao/bug-view-37382.html - * 2. just show time to full on the next refresh, it will be 60s after charging. - * \warn Add frequency of refresh battry will take a lot of overhead in cpu - * refresh battry every 1s take 5% cpu performence on arm laptop - */ - if bat.Status == battery.StatusDischarging { - logger.Debug("Just started charging") - setTimeToFull = false - } - } - - bat._refresh(batInfo, setTimeToFull) - if endDelay != nil { - err := endDelay() - if err != nil { - logger.Warning(err) - } - } - ok = true - return -} - -func (bat *Battery) _refresh(info *battery.BatteryInfo, setTimeToFull bool) { - logger.Debug("Refresh", bat.Name) - isPresent := true - var updateTime int64 - if info == nil { - isPresent = false - info = &battery.BatteryInfo{} - } else { - now := time.Now() - updateTime = now.Unix() - logger.Debugf("now %v updateTime %v", now, updateTime) - } - - logger.Debug("Name", info.Name) - logger.Debug("Technology", info.Technology) - logger.Debug("Manufacturer", info.Manufacturer) - logger.Debug("ModelName", info.ModelName) - logger.Debug("SerialNumber", info.SerialNumber) - logger.Debugf("energy %v", info.Energy) - logger.Debugf("energyFull %v", info.EnergyFull) - logger.Debugf("EnergyFullDesign %v", info.EnergyFullDesign) - logger.Debugf("EnergyRate %v", info.EnergyRate) - logger.Debugf("voltage %v", info.Voltage) - logger.Debugf("percentage %.4f%%", info.Percentage) - logger.Debugf("capacity %.4f%%", info.Capacity) - logger.Debug("status", info.Status) - logger.Debugf("timeToEmpty %v (%vs), timeToFull %v (%vs)", - time.Duration(info.TimeToEmpty)*time.Second, - info.TimeToEmpty, - time.Duration(info.TimeToFull)*time.Second, - info.TimeToFull) - - bat.PropsMu.Lock() - bat.setPropIsPresent(isPresent) - bat.setPropUpdateTime(updateTime) - bat.setPropName(info.Name) - bat.setPropTechnology(info.Technology) - bat.setPropManufacturer(info.Manufacturer) - bat.setPropModelName(info.ModelName) - bat.setPropSerialNumber(info.SerialNumber) - bat.setPropEnergy(info.Energy) - bat.setPropEnergyFull(info.EnergyFull) - bat.setPropEnergyFullDesign(info.EnergyFullDesign) - bat.setPropEnergyRate(info.EnergyRate) - bat.setPropVoltage(info.Voltage) - bat.setPropPercentage(info.Percentage) - bat.setPropCapacity(info.Capacity) - bat.setPropStatus(info.Status) - bat.setPropTimeToEmpty(info.TimeToEmpty) - if setTimeToFull { - bat.setPropTimeToFull(info.TimeToFull) - } else { - bat.setPropTimeToFull(0) - } - bat.PropsMu.Unlock() - - logger.Debugf("Refresh %v done", bat.Name) - if bat.refreshDone != nil { - bat.refreshDone() - } -} - -func (bat *Battery) Refresh() { - dev := bat.newDevice() - if dev != nil { - bat.refresh(dev) - dev.Unref() - } else { - logger.Warningf("Refresh %v failed", bat.Name) - } -} - -func (bat *Battery) startLoopUpdate(d time.Duration) chan struct{} { - done := make(chan struct{}, 1) - go func() { - ticker := time.NewTicker(d) - defer ticker.Stop() - for { - select { - case _, ok := <-ticker.C: - if !ok { - logger.Error("Invalid ticker event") - return - } - - bat.Refresh() - case <-done: - return - } - } - }() - return done -} - -func (bat *Battery) resetUpdateInterval(d time.Duration) { - if bat.exit != nil { - close(bat.exit) - } - bat.exit = bat.startLoopUpdate(d) -} - -func (bat *Battery) destroy() { - if bat.exit != nil { - close(bat.exit) - bat.exit = nil - } -} diff --git a/system/power1/battery_display.go b/system/power1/battery_display.go deleted file mode 100644 index 59d6f831f..000000000 --- a/system/power1/battery_display.go +++ /dev/null @@ -1,151 +0,0 @@ -// SPDX-FileCopyrightText: 2018 - 2022 UnionTech Software Technology Co., Ltd. -// -// SPDX-License-Identifier: GPL-3.0-or-later - -package power - -import ( - "time" - - "github.com/linuxdeepin/dde-api/powersupply/battery" -) - -func (m *Manager) refreshBatteryDisplay() { - logger.Debug("refreshBatteryDisplay") - defer func() { - timestamp := time.Now().Unix() - err := m.service.Emit(m, "BatteryDisplayUpdate", timestamp) - if err != nil { - logger.Warning(err) - } - }() - - var percentage float64 - var status battery.Status - var timeToEmpty, timeToFull uint64 - var energyCapacity, energyFullTotal, energyFullDesignTotal float64 - - batteryCount := len(m.batteries) - if batteryCount == 0 { - m.resetBatteryDisplay() - return - } else if batteryCount == 1 { - var bat0 *Battery - for _, bat := range m.batteries { - bat0 = bat - break - } - - // copy from bat0 - if bat0 != nil { - bat0.PropsMu.RLock() - percentage = bat0.Percentage - status = bat0.Status - timeToEmpty = bat0.TimeToEmpty - timeToFull = bat0.TimeToFull - energyFullTotal = bat0.EnergyFull - energyFullDesignTotal = bat0.EnergyFullDesign - bat0.PropsMu.RUnlock() - } - } else { - var energyTotal, energyRateTotal float64 - statusSlice := make([]battery.Status, 0, batteryCount) - for _, bat := range m.batteries { - bat.PropsMu.RLock() - energyTotal += bat.Energy - energyFullTotal += bat.EnergyFull - energyFullDesignTotal += bat.EnergyFullDesign - energyRateTotal += bat.EnergyRate - statusSlice = append(statusSlice, bat.Status) - bat.PropsMu.RUnlock() - } - logger.Debugf("energyTotal: %v", energyTotal) - logger.Debugf("energyFullTotal: %v", energyFullTotal) - logger.Debugf("energyRateTotal: %v", energyRateTotal) - - percentage = rightPercentage(energyTotal / energyFullTotal * 100.0) - status = battery.GetDisplayStatus(statusSlice) - - if energyRateTotal > 0 { - if status == battery.StatusDischarging { - timeToEmpty = uint64(3600 * (energyTotal / energyRateTotal)) - } else if status == battery.StatusCharging { - timeToFull = uint64(3600 * ((energyFullTotal - energyTotal) / energyRateTotal)) - } - } - /* check the remaining time is under a set limit, to deal with broken - primary batteries rate */ - if timeToEmpty > 240*60*60 { /* ten days for discharging */ - timeToEmpty = 0 - } - if timeToFull > 20*60*60 { /* 20 hours for charging */ - timeToFull = 0 - } - } - // 更新manager的battery status - if status == battery.StatusUnknown { - if m.OnBattery { - status = battery.StatusDischarging - } else { - if percentage == 100 { - status = battery.StatusFull - timeToFull = 0 - } else { - status = battery.StatusNotCharging - } - } - } - m.changeBatteryLowByBatteryPercentage(percentage) - // report - m.PropsMu.Lock() - m.setPropHasBattery(true) - m.setPropBatteryPercentage(percentage) - m.setPropBatteryStatus(status) - m.setPropBatteryTimeToEmpty(timeToEmpty) - m.setPropBatteryTimeToFull(timeToFull) - energyCapacity = rightPercentage(energyFullTotal / energyFullDesignTotal * 100.0) - m.setPropBatteryCapacity(energyCapacity) - m.PropsMu.Unlock() - - logger.Debugf("BatteryCapacity %.1f%%", energyCapacity) - logger.Debugf("percentage: %.1f%%", percentage) - logger.Debug("status:", status, uint32(status)) - logger.Debugf("timeToEmpty %v (%vs), timeToFull %v (%vs)", - time.Duration(timeToEmpty)*time.Second, - timeToEmpty, - time.Duration(timeToFull)*time.Second, - timeToFull) - // callback中修改所有电池的状态 - for _, bat := range m.batteries { - bat.setPropStatus(status) - } -} - -func (m *Manager) changeBatteryLowByBatteryPercentage(percentage float64) { - logger.Debug("changeBatteryLowByBatteryPercentage, battery percentage: ", percentage) - batteryLow := percentage <= float64(m.PowerSavingModeAutoBatteryPercent) - if m.batteryLow != batteryLow { - m.batteryLow = batteryLow - m.updatePowerMode(false) // refresh battery percentage - } -} - -func (m *Manager) resetBatteryDisplay() { - m.PropsMu.Lock() - m.setPropHasBattery(false) - m.setPropBatteryPercentage(0) - m.setPropBatteryStatus(battery.StatusUnknown) - m.setPropBatteryTimeToEmpty(0) - m.setPropBatteryTimeToFull(0) - m.setPropBatteryCapacity(0) - m.PropsMu.Unlock() -} - -func rightPercentage(val float64) float64 { - if val < 0.0 { - val = 0.0 - } else if val > 100.0 { - val = 100.0 - } - return val -} diff --git a/system/power1/battery_display_test.go b/system/power1/battery_display_test.go deleted file mode 100644 index 296bd2f93..000000000 --- a/system/power1/battery_display_test.go +++ /dev/null @@ -1,45 +0,0 @@ -// SPDX-FileCopyrightText: 2022 UnionTech Software Technology Co., Ltd. -// -// SPDX-License-Identifier: GPL-3.0-or-later - -package power - -import ( - "testing" - - "github.com/stretchr/testify/assert" -) - -func Test_rightPercentage(t *testing.T) { - var data float64 - data = -50.75 - assert.Equal(t, rightPercentage(data), 0.0) - data = 66.66 - assert.Equal(t, rightPercentage(data), 66.66) - data = 123.111 - assert.Equal(t, rightPercentage(data), 100.0) -} - -func Test_changeBatteryLowByBatteryPercentage(t *testing.T) { - m := Manager{} - - percentage := float64(m.PowerSavingModeAutoBatteryPercent - 1) - m.changeBatteryLowByBatteryPercentage(percentage) - - percentage = float64(m.PowerSavingModeAutoBatteryPercent + 1) - m.changeBatteryLowByBatteryPercentage(percentage) - - percentage = float64(m.PowerSavingModeAutoBatteryPercent + 1) - m.batteryLow = false - m.changeBatteryLowByBatteryPercentage(percentage) - - percentage = float64(m.PowerSavingModeAutoBatteryPercent + 1) - m.batteryLow = true - m.changeBatteryLowByBatteryPercentage(percentage) -} - -func Test_ManagerSimpleFunc(t *testing.T) { - m := Manager{} - - m.resetBatteryDisplay() -} diff --git a/system/power1/battery_history.go b/system/power1/battery_history.go deleted file mode 100644 index 755dd35cd..000000000 --- a/system/power1/battery_history.go +++ /dev/null @@ -1,37 +0,0 @@ -// SPDX-FileCopyrightText: 2022 UnionTech Software Technology Co., Ltd. -// -// SPDX-License-Identifier: GPL-3.0-or-later - -package power - -import "math" - -/* 记录数量 */ -func (bat *Battery) getHistoryLength() int { - return len(bat.batteryHistory) -} - -/* 插入记录 */ -func (bat *Battery) appendToHistory(percentage float64) { - bat.batteryHistory = append(bat.batteryHistory, percentage) - if len(bat.batteryHistory) > 10 { - bat.batteryHistory = bat.batteryHistory[1:] - } -} - -/* 计算方差 */ -func (bat *Battery) calcHistoryVariance() float64 { - var average float64 = 0.0 - for i := range bat.batteryHistory { - average += bat.batteryHistory[i] - } - average /= float64(len(bat.batteryHistory)) - - var variance = 0.0 - for i := range bat.batteryHistory { - variance += math.Pow(bat.batteryHistory[i]-average, 2) - } - variance /= float64(len(bat.batteryHistory)) - - return variance -} diff --git a/system/power1/battery_history_test.go b/system/power1/battery_history_test.go deleted file mode 100644 index c51d76263..000000000 --- a/system/power1/battery_history_test.go +++ /dev/null @@ -1,43 +0,0 @@ -// SPDX-FileCopyrightText: 2018 - 2022 UnionTech Software Technology Co., Ltd. -// -// SPDX-License-Identifier: GPL-3.0-or-later - -package power - -import ( - "github.com/stretchr/testify/assert" - "testing" -) - -func Test_getHistoryLength(t *testing.T) { - bat := Battery{} - bat.batteryHistory = []float64{1.0, 2.0} - len := bat.getHistoryLength() - assert.Equal(t, 2, len) -} - -func Test_appendToHistory(t *testing.T) { - bat := Battery{} - - bat.appendToHistory(1.0) - assert.Equal(t, 1.0, bat.batteryHistory[0]) - - bat.appendToHistory(2.0) - bat.appendToHistory(3.0) - bat.appendToHistory(4.0) - bat.appendToHistory(5.0) - bat.appendToHistory(6.0) - bat.appendToHistory(7.0) - bat.appendToHistory(8.0) - bat.appendToHistory(9.0) - bat.appendToHistory(10.0) - assert.Equal(t, 10.0, bat.batteryHistory[9]) -} - -func Test_calcHistoryVariance(t *testing.T) { - bat := Battery{} - - bat.batteryHistory = []float64{1.0, 2.0} - variance := bat.calcHistoryVariance() - assert.Equal(t, 0.25, variance) -} diff --git a/system/power1/battery_test.go b/system/power1/battery_test.go deleted file mode 100644 index fa63bd388..000000000 --- a/system/power1/battery_test.go +++ /dev/null @@ -1,30 +0,0 @@ -// SPDX-FileCopyrightText: 2018 - 2022 UnionTech Software Technology Co., Ltd. -// -// SPDX-License-Identifier: GPL-3.0-or-later - -package power - -import ( - "testing" - - "github.com/stretchr/testify/assert" -) - -func Test_checkTimeStabilized(t *testing.T) { - data := []uint64{ - 9455, - 5467, - 3840, - 2962, - 2408, - 2408, - 1754, - 1698, - 1710, - 1675, - } - - assert.False(t, checkTimeStabilized(data[:2], data[2])) - assert.False(t, checkTimeStabilized(data[:6], data[6])) - assert.True(t, checkTimeStabilized(data[:9], data[9])) -} diff --git a/system/power1/daemon.go b/system/power1/daemon.go deleted file mode 100644 index 8219a4b33..000000000 --- a/system/power1/daemon.go +++ /dev/null @@ -1,202 +0,0 @@ -// SPDX-FileCopyrightText: 2018 - 2026 UnionTech Software Technology Co., Ltd. -// -// SPDX-License-Identifier: GPL-3.0-or-later - -package power - -import ( - "errors" - "github.com/godbus/dbus/v5" - "github.com/linuxdeepin/dde-daemon/loader" - "github.com/linuxdeepin/go-lib/dbusutil" - "github.com/linuxdeepin/go-lib/log" - "sync" -) - -var logger = log.NewLogger("daemon/system/power") - -func init() { - loader.Register(NewDaemon(logger)) -} - -type Daemon struct { - *loader.ModuleBase - managerMu sync.RWMutex - manager *Manager -} - -func NewDaemon(logger *log.Logger) *Daemon { - daemon := new(Daemon) - daemon.ModuleBase = loader.NewModuleBase("power", daemon, logger) - return daemon -} -func (d *Daemon) ShortIdleState() (bool, error) { - d.managerMu.RLock() - defer d.managerMu.RUnlock() - - manager := d.manager - if manager == nil { - return false, errors.New("power manager is not initialized") - } - return manager.getShortIdleState(), nil -} - -func (d *Daemon) SetShortIdleState(state bool) error { - d.managerMu.RLock() - defer d.managerMu.RUnlock() - - manager := d.manager - if manager == nil { - return errors.New("power manager is not initialized") - } - return manager.setShortIdleState(state) -} - - -func (d *Daemon) GetDependencies() []string { - return []string{} -} - -func (d *Daemon) Start() (err error) { - d.managerMu.Lock() - defer d.managerMu.Unlock() - - service := loader.GetService() - manager, err := newManager(service) - if err != nil { - return - } - d.manager = manager - - manager.batteriesMu.Lock() - for _, bat := range manager.batteries { - err := service.Export(bat.getObjPath(), bat) - if err != nil { - logger.Warning("failed to export battery:", err) - } - } - manager.batteriesMu.Unlock() - serverObj, err := service.NewServerObject(dbusPath, manager) - if err != nil { - return - } - err = serverObj.ConnectChanged(manager, "PowerSavingModeAuto", func(change *dbusutil.PropertyChanged) { - manager.updatePowerMode(false) // PowerSavingModeAuto change - err := manager.saveDsgConfig("PowerSavingModeAuto") - if err != nil { - logger.Warning(err) - } - }) - if err != nil { - logger.Warning(err) - } - - err = serverObj.ConnectChanged(manager, "PowerSavingModeEnabled", func(change *dbusutil.PropertyChanged) { - enabled := change.Value.(bool) - manager.PropsMu.Lock() - manager.updatePowerSavingState(false) - manager.PropsMu.Unlock() - // 历史版本只有节能和平衡之间的切换 - if enabled { - manager.doSetMode(ddePowerSave) - } else { - manager.doSetMode(ddeBalance) - } - err := manager.saveDsgConfig("PowerSavingModeEnabled") - if err != nil { - logger.Warning(err) - } - }) - if err != nil { - logger.Warning(err) - } - - // 属性改变后的回调函数 - err = serverObj.ConnectChanged(manager, "PowerSavingModeAutoWhenBatteryLow", func(change *dbusutil.PropertyChanged) { - manager.refreshBatteryDisplay() - manager.updatePowerMode(false) // PowerSavingModeAutoWhenBatteryLow change - err := manager.saveDsgConfig("PowerSavingModeAutoWhenBatteryLow") - if err != nil { - logger.Warning(err) - } - }) - if err != nil { - logger.Warning(err) - } - - err = serverObj.ConnectChanged(manager, "PowerSavingModeBrightnessDropPercent", func(change *dbusutil.PropertyChanged) { - err := manager.saveDsgConfig("PowerSavingModeBrightnessDropPercent") - if err != nil { - logger.Warning(err) - } - }) - if err != nil { - logger.Warning(err) - } - - err = serverObj.ConnectChanged(manager, "PowerSavingModeAutoBatteryPercent", func(change *dbusutil.PropertyChanged) { - manager.refreshBatteryDisplay() - manager.updatePowerMode(false) // PowerSavingModeAutoBatteryPercent change - err := manager.saveDsgConfig("PowerSavingModeAutoBatteryPercent") - if err != nil { - logger.Warning(err) - } - }) - if err != nil { - logger.Warning(err) - } - if manager.enablePerformanceInBoot() { - var handlerId dbusutil.SignalHandlerId - handlerId, err = manager.displayManager.ConnectSessionAdded(func(session dbus.ObjectPath) { - // 登录前tlpMode都是performance,不设置电源模式,直到有第一个用户登录了才设置电源模式 - displaySessions, err := manager.displayManager.Sessions().Get(0) - if err != nil { - logger.Warning(err) - } - if len(displaySessions) == 1 { - manager.updatePowerMode(true) - } - manager.displayManager.RemoveHandler(handlerId) - }) - if err != nil { - logger.Warning(err) - } - } - err = serverObj.Export() - if err != nil { - logger.Warning(err) - return - } - - err = service.RequestName(dbusServiceName) - return -} - -func (d *Daemon) Stop() error { - d.managerMu.Lock() - defer d.managerMu.Unlock() - - manager := d.manager - if manager == nil { - return nil - } - service := loader.GetService() - - manager.batteriesMu.Lock() - for _, bat := range manager.batteries { - err := service.StopExport(bat) - if err != nil { - logger.Warning(err) - } - } - manager.batteriesMu.Unlock() - - err := service.StopExport(manager) - if err != nil { - logger.Warning(err) - } - - manager.destroy() - d.manager = nil - return nil -} diff --git a/system/power1/exported_methods_auto.go b/system/power1/exported_methods_auto.go deleted file mode 100644 index efbd96693..000000000 --- a/system/power1/exported_methods_auto.go +++ /dev/null @@ -1,62 +0,0 @@ -// Code generated by "dbusutil-gen em -type Manager,Battery"; DO NOT EDIT. - -package power - -import ( - "github.com/linuxdeepin/go-lib/dbusutil" -) - -func (v *Battery) GetExportedMethods() dbusutil.ExportedMethods { - return nil -} -func (v *Manager) GetExportedMethods() dbusutil.ExportedMethods { - return dbusutil.ExportedMethods{ - { - Name: "GetBatteries", - Fn: v.GetBatteries, - OutArgs: []string{"batteries"}, - }, - { - Name: "LockCpuFreq", - Fn: v.LockCpuFreq, - InArgs: []string{"governor", "lockTime"}, - }, - { - Name: "Refresh", - Fn: v.Refresh, - }, - { - Name: "RefreshBatteries", - Fn: v.RefreshBatteries, - }, - { - Name: "RefreshMains", - Fn: v.RefreshMains, - }, - { - Name: "SetAllowCaller", - Fn: v.SetAllowCaller, - InArgs: []string{"uniqueName"}, - }, - { - Name: "SetCpuBoost", - Fn: v.SetCpuBoost, - InArgs: []string{"enabled"}, - }, - { - Name: "SetCpuGovernor", - Fn: v.SetCpuGovernor, - InArgs: []string{"governor"}, - }, - { - Name: "SetMode", - Fn: v.SetMode, - InArgs: []string{"mode"}, - }, - { - Name: "SetTlpMode", - Fn: v.SetTlpMode, - InArgs: []string{"mode"}, - }, - } -} diff --git a/system/power1/lid_switch.go b/system/power1/lid_switch.go deleted file mode 100644 index 059e15c17..000000000 --- a/system/power1/lid_switch.go +++ /dev/null @@ -1,48 +0,0 @@ -// SPDX-FileCopyrightText: 2018 - 2022 UnionTech Software Technology Co., Ltd. -// -// SPDX-License-Identifier: GPL-3.0-or-later - -package power - -import ( - hostname1 "github.com/linuxdeepin/go-dbus-factory/system/org.freedesktop.hostname1" - "github.com/linuxdeepin/go-lib/arch" -) - -func (m *Manager) initLidSwitch() { - hostnameObj := hostname1.NewHostname(m.service.Conn()) - chassis, err := hostnameObj.Chassis().Get(0) - if err != nil { - logger.Warningf("failed to get chassis type(%v)", err) - return - } - if chassis == "convertible" || chassis == "laptop" { - if arch.Get() == arch.Sunway && isSWLidStateFileExist() { - m.initLidSwitchSW() - } else { - err := m.initLidSwitchByUPower() - if err != nil { - logger.Warningf("failed to init watch lid switch by upower(%v),start init watch by gudev", err) - m.initLidSwitchCommon() - } - } - } - logger.Debug("hasLidSwitch:", m.HasLidSwitch) -} - -func (m *Manager) handleLidSwitchEvent(closed bool) { - m.LidClosed = closed - if closed { - logger.Info("Lid Closed") - err := m.service.Emit(m, "LidClosed") - if err != nil { - logger.Warning(err) - } - } else { - logger.Info("Lid Opened") - err := m.service.Emit(m, "LidOpened") - if err != nil { - logger.Warning(err) - } - } -} diff --git a/system/power1/lid_switch_common.go b/system/power1/lid_switch_common.go deleted file mode 100644 index 08f22af15..000000000 --- a/system/power1/lid_switch_common.go +++ /dev/null @@ -1,236 +0,0 @@ -// SPDX-FileCopyrightText: 2018 - 2022 UnionTech Software Technology Co., Ltd. -// -// SPDX-License-Identifier: GPL-3.0-or-later - -package power - -/* -#include -*/ -import "C" - -import ( - "bytes" - "encoding/binary" - "fmt" - "os" - "strconv" - "strings" - "syscall" - "unsafe" - - upower "github.com/linuxdeepin/go-dbus-factory/org.freedesktop.upower" -) - -const ( - SW_LID = C.SW_LID - SW_CNT = C.SW_CNT - SW_MAX = C.SW_MAX - EV_SW = C.EV_SW - - bitsPerLong = int(unsafe.Sizeof(C.long(0))) * 8 -) - -// NBITS(x) ((((x)-1)/BITS_PER_LONG)+1) -func NBITS(x int) int { - return (((x) - 1) / bitsPerLong) + 1 -} - -// #define LONG(x) ((x)/BITS_PER_LONG) -func LONG(x int) int { - return x / bitsPerLong -} - -// #define OFF(x) ((x)%BITS_PER_LONG) -func OFF(x int) int { - return x % bitsPerLong -} - -// #define test_bit(bit, array) ((array[LONG(bit)] >> OFF(bit)) & 1) -func testBit(bit int, array []int) bool { - v := (array[LONG(bit)] >> uint(OFF(bit))) & 1 - return v != 0 -} - -func upInputStrToBitmask(s string, bitmask []int) int { - var numBitsSet int - maxSize := len(bitmask) - v := strings.SplitN(s, " ", maxSize) - - j := 0 - for i := len(v) - 1; i >= 0; i-- { - val, _ := strconv.ParseUint(v[i], 16, 64) - bitmask[j] = int(val) - - for val != 0 { - numBitsSet++ - val &= val - 1 - } - - j++ - } - return numBitsSet -} - -type InputEvent struct { - Time syscall.Timeval // time in seconds since epoch at which event occurred - Type uint16 // event type - one of ecodes.EV_* - Code uint16 // event code related to the event type - Value int32 // event value related to the event type -} - -// Get a useful description for an input event. Example: -// -// event at 1347905437.435795, code 01, type 02, val 02 -func (ev *InputEvent) String() string { - return fmt.Sprintf("event at %d.%d, code %02d, type %02d, val %02d", - ev.Time.Sec, ev.Time.Usec, ev.Code, ev.Type, ev.Value) -} - -const eventSize = int(unsafe.Sizeof(InputEvent{})) - -func (m *Manager) findLidSwitch() string { - devices := m.gudevClient.QueryBySubsystem("input") - - defer func() { - // free devices - for _, device := range devices { - device.Unref() - } - }() - - for _, device := range devices { - name := device.GetName() - if !strings.HasPrefix(name, "event") { - continue - } - - capSw := device.GetSysfsAttr("../capabilities/sw") - - bitmask := make([]int, NBITS(SW_MAX)) - numBits := upInputStrToBitmask(capSw, bitmask) - - if numBits == 0 || numBits >= SW_CNT { - // invalid bitmask entry - continue - } - - if !testBit(SW_LID, bitmask) { - // not a lid - continue - } - - deviceFile := device.GetDeviceFile() - if deviceFile != "" { - return deviceFile - } - } - return "" -} - -func (m *Manager) initLidSwitchCommon() { - devFile := m.findLidSwitch() - if devFile == "" { - logger.Info("Not found lid switch") - return - } - logger.Infof("find dev file %q", devFile) - // open - f, err := os.Open(devFile) - if err != nil { - logger.Warningf("os.Open %q err : %v", devFile, err) - return - } - m.HasLidSwitch = true - // TODO: 通过下面的方法获取不到初始状态,先默认LidClosed为false - // 可能造成问题,如果开机之前盖上了笔记本的盖子,则无法获取到正确的状态 - // 导致需要重新合盖才能触发合盖事件 - m.LidClosed = false - - go func() { - for { - events, err := readLidSwitchEvent(f) - if err != nil { - logger.Warning(err) - continue - } - for _, ev := range events { - logger.Debugf("%v", &ev) - if ev.Type == EV_SW && ev.Code == SW_LID { - logger.Infof("lid switch event value: %v", ev.Value) - var closed bool - switch ev.Value { - case 1: - closed = true - case 0: - closed = false - default: - logger.Warningf("unknown lid switch event value %v", ev.Value) - continue - } - m.handleLidSwitchEvent(closed) - } - } - } - }() -} - -func (m *Manager) initLidSwitchByUPower() error { - const UPowerServiceName = "org.freedesktop.UPower" - uPowerObj := upower.NewUPower(m.service.Conn()) - uPowerObj.InitSignalExt(m.systemSigLoop, true) - err := uPowerObj.LidIsClosed().ConnectChanged(func(hasValue bool, isClosed bool) { - if !hasValue { - return - } - m.handleLidSwitchEvent(isClosed) - }) - if err != nil { - return err - } - - hasLidSwitch, err := uPowerObj.LidIsPresent().Get(0) - if err != nil { - return err - } - - lidClosed, err := uPowerObj.LidIsClosed().Get(0) - if err != nil { - return err - } - logger.Info("init lid switch by upower, hasLidSwitch:", hasLidSwitch, " lidClosed:", lidClosed) - m.LidClosed = lidClosed - m.HasLidSwitch = hasLidSwitch - return nil -} - -func readLidSwitchEvent(f *os.File) ([]InputEvent, error) { - // read - count := 16 - - events := make([]InputEvent, count) - buffer := make([]byte, eventSize*count) - - _, err := f.Read(buffer) - if err != nil { - logger.Warning("f read err:", err) - return nil, err - } - - b := bytes.NewBuffer(buffer) - err = binary.Read(b, binary.LittleEndian, &events) - if err != nil { - logger.Warning("binary read err:", err) - return nil, err - } - - // remove trailing structures - for i := range events { - logger.Debug("i", i) - if events[i].Time.Sec == 0 { - events = events[:i] - break - } - } - return events, nil -} diff --git a/system/power1/lid_switch_common_test.go b/system/power1/lid_switch_common_test.go deleted file mode 100644 index 29c609081..000000000 --- a/system/power1/lid_switch_common_test.go +++ /dev/null @@ -1,67 +0,0 @@ -// SPDX-FileCopyrightText: 2022 UnionTech Software Technology Co., Ltd. -// -// SPDX-License-Identifier: GPL-3.0-or-later - -package power - -import ( - "strconv" - "syscall" - "testing" - - "github.com/stretchr/testify/assert" -) - -func Test_NBITS(t *testing.T) { - var data = strconv.IntSize - assert.Equal(t, NBITS(data), 1) - data = strconv.IntSize + 1 - assert.Equal(t, NBITS(data), 2) -} - -func Test_LONG(t *testing.T) { - var data = 1 - assert.Equal(t, LONG(data), 0) - data = strconv.IntSize + 1 - assert.Equal(t, LONG(data), 1) - data = strconv.IntSize * 2 - assert.Equal(t, LONG(data), 2) -} - -func Test_OFF(t *testing.T) { - var data = 1 - assert.Equal(t, OFF(data), 1) - data = 33 - assert.Equal(t, OFF(data), data%strconv.IntSize) -} - -func Test_testBit(t *testing.T) { - array := []int{2, 4} - ok := testBit(1, array) - assert.True(t, ok) - - ok = testBit(4, array) - assert.False(t, ok) -} - -func Test_upInputStrToBitmask(t *testing.T) { - bitmask := []int{20} - numBitsSet := upInputStrToBitmask("a", bitmask) - assert.Equal(t, 2, numBitsSet) -} - -func Test_String(t *testing.T) { - time := syscall.Timeval{ - Sec: 1, - Usec: 1, - } - ev := InputEvent{ - Time: time, - Type: 1, - Code: 1, - Value: 1, - } - - evString := ev.String() - assert.Equal(t, "event at 1.1, code 01, type 01, val 01", evString) -} diff --git a/system/power1/lid_switch_sw.go b/system/power1/lid_switch_sw.go deleted file mode 100644 index 1d2d1e059..000000000 --- a/system/power1/lid_switch_sw.go +++ /dev/null @@ -1,65 +0,0 @@ -// SPDX-FileCopyrightText: 2018 - 2022 UnionTech Software Technology Co., Ltd. -// -// SPDX-License-Identifier: GPL-3.0-or-later - -package power - -import ( - "os" - "strings" - "time" -) - -const ( - swLidOpen = "1" - swLidClose = "0" -) - -const swLidStateFile = "/sys/bus/platform/devices/liddev/lid_state" - -func isSWLidStateFileExist() bool { - _, err := os.Stat(swLidStateFile) - return err == nil -} - -func (m *Manager) initLidSwitchSW() { - m.HasLidSwitch = true - m.LidClosed = false - go m.swLidSwitchCheckLoop() -} - -func (m *Manager) swLidSwitchCheckLoop() { - prevState := getLidStateSW() - if prevState == swLidClose { - m.LidClosed = true - } - for { - time.Sleep(time.Second * 3) - newState := getLidStateSW() - if prevState != newState { - prevState = newState - - var closed bool - switch newState { - case swLidClose: - closed = true - case swLidOpen: - closed = false - default: - logger.Warningf("unknown lid state %q", newState) - continue - } - m.handleLidSwitchEvent(closed) - } - } -} - -// lid_state content: '1\n' -func getLidStateSW() string { - content, err := os.ReadFile(swLidStateFile) - if err != nil { - logger.Warning(err) - return swLidOpen - } - return strings.TrimRight(string(content), "\n") -} diff --git a/system/power1/manager.go b/system/power1/manager.go deleted file mode 100644 index 424ea546e..000000000 --- a/system/power1/manager.go +++ /dev/null @@ -1,921 +0,0 @@ -// SPDX-FileCopyrightText: 2018 - 2026 UnionTech Software Technology Co., Ltd. -// -// SPDX-License-Identifier: GPL-3.0-or-later - -package power - -import ( - "encoding/json" - "errors" - "fmt" - "io/ioutil" - "os" - "sync" - "time" - - dbus "github.com/godbus/dbus/v5" - "github.com/linuxdeepin/dde-api/powersupply" - "github.com/linuxdeepin/dde-api/powersupply/battery" - "github.com/linuxdeepin/dde-daemon/common/dconfig" - "github.com/linuxdeepin/dde-daemon/securityloader" - DisplayManager "github.com/linuxdeepin/go-dbus-factory/system/org.freedesktop.DisplayManager" - gudev "github.com/linuxdeepin/go-gir/gudev-1.0" - "github.com/linuxdeepin/go-lib/dbusutil" - "github.com/linuxdeepin/go-lib/strv" -) - -const ( - dsettingsAppID = "org.deepin.dde.daemon" - dsettingsPowerName = "org.deepin.dde.daemon.power" - dsettingsPowerSavingModeEnabled = "powerSavingModeEnabled" - dsettingsPowerSavingModeAuto = "powerSavingModeAuto" - dsettingsPowerSavingModeAutoWhenBatteryLow = "powerSavingModeAutoWhenBatteryLow" - dsettingsPowerSavingModeBrightnessDropPercent = "powerSavingModeBrightnessDropPercent" - dsettingsPowerSavingModeAutoBatteryPercent = "powerSavingModeAutoBatteryPercent" - dsettingsPowerMappingConfig = "powerMappingConfig" - dsettingsMode = "mode" - dsettingsShortIdleEnable = "shortIdleEnable" - dsettingsShortIdleState = "shortIdleState" -) - -type supportMode struct { - Balance bool `json:"balance"` - Performace bool `json:"performace"` - PowerSave bool `json:"powersave"` -} - -//go:generate dbusutil-gen -type Manager,Battery -import github.com/linuxdeepin/dde-api/powersupply/battery manager.go battery.go -//go:generate dbusutil-gen em -type Manager,Battery - -// https://www.kernel.org/doc/Documentation/power/power_supply_class.txt -type Manager struct { - service *dbusutil.Service - allowCallers *securityloader.AllowCallerRegistry - systemSigLoop *dbusutil.SignalLoop - batteries map[string]*Battery - batteriesMu sync.Mutex - ac *AC - gudevClient *gudev.Client - dsgPower *dconfig.DConfig - // 电池是否电量低 - batteryLow bool - // 初始化是否完成 - initDone bool - - // INFO: pstate中,可选项是performance balance_performance balance_power power - - PropsMu sync.RWMutex - OnBattery bool - HasLidSwitch bool - LidClosed bool - // battery display properties: - HasBattery bool - BatteryPercentage float64 - BatteryStatus battery.Status - BatteryTimeToEmpty uint64 - BatteryTimeToFull uint64 - // 电池容量 - BatteryCapacity float64 - - // 开启和关闭节能模式 - PowerSavingModeEnabled bool `prop:"access:rw"` - - // 自动切换节能模式,依据为是否插拔电源 - PowerSavingModeAuto bool `prop:"access:rw"` - - // 低电量时自动开启 - PowerSavingModeAutoWhenBatteryLow bool `prop:"access:rw"` - - // 开启节能模式时降低亮度的百分比值 - PowerSavingModeBrightnessDropPercent uint32 `prop:"access:rw"` - - // 开启自动节能模式电量的百分比值 - PowerSavingModeAutoBatteryPercent uint32 `prop:"access:rw"` - - // 开启节能模式时保存的数据 - PowerSavingModeBrightnessData string `prop:"access:rw"` - - // 当前短idle状态 - ShortIdleState bool - ShortIdleStateMu sync.RWMutex - - // 是否支持短idle方案 - shortIdleEnableMu sync.RWMutex - shortIdleEnable bool - - // 直接设置tlp配置 - TlpMode string - - // CPU频率调节模式,支持powersave和performance - CpuGovernor string - - // CPU频率增强是否开启 - CpuBoost bool - - // 是否支持Boost - IsHighPerformanceSupported bool - - // 是否支持平衡模式 - IsBalanceSupported bool - - // 是否支持节能模式 - IsPowerSaveSupported bool - - // 是否支持切换性能模式 - SupportSwitchPowerMode bool `prop:"access:rw"` - // 当前模式 - Mode string - - // 上次非低电量时的模式 - lastMode string - - displayManager DisplayManager.DisplayManager - - isLowBatteryMode bool - - dspcMu sync.Mutex - - // nolint - signals *struct { - BatteryDisplayUpdate struct { - timestamp int64 - } - - BatteryAdded struct { - path dbus.ObjectPath - } - - BatteryRemoved struct { - path dbus.ObjectPath - } - - LidClosed struct{} - LidOpened struct{} - } -} - -const ( - ddePowerSave = "powersave" - ddeBalance = "balance" - ddePerformance = "performance" - ddeLowBattery = "lowBattery" // 内部使用,在对外暴露的时候,会切换成powersave - - shortIdleWifiOn = "on" - shortIdleWifiOff = "off" -) - -var _allPowerModeArray = []string{ - ddePowerSave, - ddeBalance, - ddePerformance, - ddeLowBattery, -} - -var _validPowerModeArray = strv.Strv{ - ddePowerSave, - ddeBalance, - ddePerformance, - ddeLowBattery, -} -func newManager(service *dbusutil.Service) (*Manager, error) { - m := &Manager{ - service: service, - BatteryPercentage: 100, - lastMode: ddeBalance, - IsHighPerformanceSupported: true, - IsBalanceSupported: true, - IsPowerSaveSupported: true, - CpuBoost: true, - allowCallers: securityloader.DefaultRegistry(), - } - - err := m.init() - if err != nil { - m.destroy() - return nil, err - } - - return m, nil -} - -type AC struct { - gudevClient *gudev.Client - sysfsPath string -} - -func newAC(manager *Manager, device *gudev.Device) *AC { - sysfsPath := device.GetSysfsPath() - return &AC{ - gudevClient: manager.gudevClient, - sysfsPath: sysfsPath, - } -} - -func (ac *AC) newDevice() *gudev.Device { - return ac.gudevClient.QueryBySysfsPath(ac.sysfsPath) -} - -func (m *Manager) refreshAC(ac *gudev.Device) { // 拔插电源时候触发 - online := ac.GetPropertyAsBoolean("POWER_SUPPLY_ONLINE") - logger.Debug("ac online:", online) - onBattery := !online - - m.PropsMu.Lock() - m.setPropOnBattery(onBattery) - m.PropsMu.Unlock() - // 根据OnBattery的状态,修改节能模式 - m.updatePowerMode(false) // refreshAC -} - -func (m *Manager) initAC(devices []*gudev.Device) { - var ac *gudev.Device - for _, dev := range devices { - if powersupply.IsMains(dev) { - ac = dev - break - } - } - if ac != nil { - m.refreshAC(ac) - m.ac = newAC(m, ac) - } -} - -func (m *Manager) init() error { - m.systemSigLoop = dbusutil.NewSignalLoop(m.service.Conn(), 10) - m.systemSigLoop.Start() - err := m.initDsgConfig() - if err != nil { - logger.Warning(err) - } - - subsystems := []string{"power_supply", "input"} - m.gudevClient = gudev.NewClient(subsystems) - if m.gudevClient == nil { - return errors.New("gudevClient is nil") - } - - m.initLidSwitch() - devices := powersupply.GetDevices(m.gudevClient) - - m.initAC(devices) - m.initBatteries(devices) - for _, dev := range devices { - dev.Unref() - } - - m.gudevClient.Connect("uevent", m.handleUEvent) - m.initDone = true - - // m.updatePowerMode(true) // init - - m.displayManager = DisplayManager.NewDisplayManager(m.service.Conn()) - m.displayManager.InitSignalExt(m.systemSigLoop, true) - return nil -} - -func (m *Manager) initDsgConfig() error { - logger.Info("org.deepin.dde.Power1 module start init dconfig.") - // dsg 配置 - // ds := ConfigManager.NewConfigManager(m.service.Conn()) - - // dsPowerPath, err := ds.AcquireManager(0, dsettingsAppID, dsettingsPowerName, "") - // if err != nil { - // return err - // } - // dsPower, err := ConfigManager.NewManager(m.service.Conn(), dsPowerPath) - dsPower, err := dconfig.NewDConfig(dsettingsAppID, dsettingsPowerName, "") - if err != nil { - return err - } - m.dsgPower = dsPower - - cfg := loadConfigSafe() - if cfg != nil { - // 将config.json中的配置完成初始化 - m.PowerSavingModeEnabled = cfg.PowerSavingModeEnabled // 开启和关闭节能模式 - m.PowerSavingModeAuto = cfg.PowerSavingModeAuto // 自动切换节能模式,依据为是否插拔电源 - m.PowerSavingModeAutoWhenBatteryLow = cfg.PowerSavingModeAutoWhenBatteryLow // 低电量时自动开启 - m.PowerSavingModeBrightnessDropPercent = cfg.PowerSavingModeBrightnessDropPercent // 开启节能模式时降低亮度的百分比值 - m.PowerSavingModeAutoBatteryPercent = cfg.PowerSavingModeAutoBatteryPercent // 开启在低电量自动节能模式时候的百分比 - m.Mode = cfg.Mode - migrateErr := m.migrateFromCurrentConfigsToDsg() - if migrateErr != nil { - logger.Error("migrateFromCurrentConfigsToDsg failed, err:", migrateErr) - } - } - - getPowerSavingModeAuto := func(init bool) { - data, err := dsPower.GetValueBool(dsettingsPowerSavingModeAuto) - if err != nil { - logger.Warning(err) - return - } - - if init { - m.PowerSavingModeAuto = data - return - } - - m.setPropPowerSavingModeAuto(data) - } - - getPowerSavingModeEnabled := func(init bool) { - data, err := dsPower.GetValueBool(dsettingsPowerSavingModeEnabled) - if err != nil { - logger.Warning(err) - return - } - - if init { - m.PowerSavingModeEnabled = data - return - } - - m.setPropPowerSavingModeEnabled(data) - } - - getPowerSavingModeAutoWhenBatteryLow := func(init bool) { - data, err := dsPower.GetValueBool(dsettingsPowerSavingModeAutoWhenBatteryLow) - if err != nil { - logger.Warning(err) - return - } - - if init { - m.PowerSavingModeAutoWhenBatteryLow = data - return - } - - m.setPropPowerSavingModeAutoWhenBatteryLow(data) - } - - getPowerSavingModeBrightnessDropPercent := func(init bool) { - data, err := dsPower.GetValueInt64(dsettingsPowerSavingModeBrightnessDropPercent) - if err != nil { - logger.Warning(err) - return - } - - if init { - m.PowerSavingModeBrightnessDropPercent = uint32(data) - return - } - - ret := false - m.setPropPowerSavingModeBrightnessDropPercent(uint32(data)) - if ret { - logger.Info("Set power saving mode brightness drop percent", m.PowerSavingModeBrightnessDropPercent) - } - } - getPowerSavingModeAutoBatteryPercent := func(init bool) { - data, err := dsPower.GetValueInt64(dsettingsPowerSavingModeAutoBatteryPercent) - if err != nil { - logger.Warning(err) - return - } - - if init { - m.PowerSavingModeAutoBatteryPercent = uint32(data) - return - } - - ret := false - m.setPropPowerSavingModeAutoBatteryPercent(uint32(data)) - if ret { - logger.Info("Set power saving mode auto battery percent", m.PowerSavingModeAutoBatteryPercent) - } - } - - getMode := func(init bool) string { - value, err := dsPower.GetValueString(dsettingsMode) - if err != nil { - logger.Warning(err) - return ddeBalance - } - logger.Infof("value:%v", value) - // dsg更新配置后,校验mode有效性 - if !_validPowerModeArray.Contains(value) { - value = ddeBalance - _ = m.setDsgData(dsettingsMode, value, m.dsgPower) // 将修正后的数据回写dconfig - } - if init { - logger.Info("init ") - m.Mode = value - return value - } - m.setPropMode(value) - return value - } - - getPowerMappingConfig := func() { - configStr, err := dsPower.GetValueString(dsettingsPowerMappingConfig) - if err != nil { - logger.Warning(err) - return - } - config := make(map[string]powerConfig) - err = json.Unmarshal([]byte(configStr), &config) - if err != nil { - logger.Warning(err) - return - } - - for _, mode := range _allPowerModeArray { - c, ok := config[mode] - if ok { - _powerConfigMap[mode].DSPCConfig = c.DSPCConfig - } - } - } - - getPowerSavingModeAuto(true) - getPowerSavingModeEnabled(true) - getPowerSavingModeAutoWhenBatteryLow(true) - getPowerSavingModeBrightnessDropPercent(true) - getPowerSavingModeAutoBatteryPercent(true) - getMode(true) - getPowerMappingConfig() - - getShortIdleEnable := func() { - data, err := dsPower.GetValueBool(dsettingsShortIdleEnable) - if err != nil { - logger.Warning(err) - return - } - m.setShortIdleEnable(data) - logger.Info("dsg of shortIdleEnable : ", data) - } - getShortIdleEnable() - - dsPower.ConnectValueChanged(func(key string) { - logger.Info("dconfig org.deepin.dde.daemon.power valueChanged, key : ", key) - validValue := true - switch key { - case dsettingsPowerSavingModeAuto: - getPowerSavingModeAuto(false) - case dsettingsPowerSavingModeEnabled: - getPowerSavingModeEnabled(false) - case dsettingsPowerSavingModeAutoWhenBatteryLow: - getPowerSavingModeAutoWhenBatteryLow(false) - case dsettingsPowerSavingModeBrightnessDropPercent: - getPowerSavingModeBrightnessDropPercent(false) - case dsettingsPowerSavingModeAutoBatteryPercent: - getPowerSavingModeAutoBatteryPercent(false) - case dsettingsMode: - oldMode := m.Mode - newMode := getMode(false) - if oldMode == newMode { - return - } - // 手动(外部请求)切换到节能模式,或节能模式切换到其他模式时,关闭电池自动节能和低电量自动节能 - if ddePowerSave == oldMode || ddePowerSave == newMode { - m.PropsMu.Lock() - m.updatePowerSavingState(false) - m.PropsMu.Unlock() - } - m.doSetMode(newMode) - return - case dsettingsPowerMappingConfig: - getPowerMappingConfig() - case dsettingsShortIdleEnable: - getShortIdleEnable() - default: - validValue = false - logger.Debug("Not process. valueChanged, key : ", key) - } - if validValue { - m.updatePowerMode(false) // dconfig change - } - }) - - return nil -} - -func (m *Manager) handleUEvent(client *gudev.Client, action string, device *gudev.Device) { - logger.Debug("on uevent action:", action) - defer device.Unref() - - switch action { - case "change": - if powersupply.IsMains(device) { - if m.ac == nil { - m.ac = newAC(m, device) - } else if m.ac.sysfsPath != device.GetSysfsPath() { - logger.Warning("found another AC", device.GetSysfsPath()) - return - } - - // now m.ac != nil, and sysfsPath equal - m.refreshAC(device) - time.AfterFunc(1*time.Second, m.refreshBatteries) - time.AfterFunc(3*time.Second, m.refreshBatteries) - // 电源状态变更时,需要一段时间才能稳定,因此在1分钟内,每隔5秒刷新一次,保证数据及时更新 - for i := 1; i <= 12; i++ { - time.AfterFunc(time.Duration(i*5)*time.Second, m.refreshBatteries) - } - } else if powersupply.IsSystemBattery(device) { - m.addAndExportBattery(device) - } - case "add": - if powersupply.IsSystemBattery(device) { - m.addAndExportBattery(device) - } - // ignore add mains - - case "remove": - if powersupply.IsSystemBattery(device) { - m.removeBattery(device) - } - } - -} - -func (m *Manager) initBatteries(devices []*gudev.Device) { - m.batteries = make(map[string]*Battery) - for _, dev := range devices { - m.addBattery(dev) - } - logger.Debugf("initBatteries done %#v", m.batteries) -} - -func (m *Manager) addAndExportBattery(dev *gudev.Device) { - bat, added := m.addBattery(dev) - if added { - err := m.service.Export(bat.getObjPath(), bat) - if err == nil { - m.emitBatteryAdded(bat) - } else { - logger.Warning("failed to export battery:", err) - } - } -} - -func (m *Manager) addBattery(dev *gudev.Device) (*Battery, bool) { - logger.Debug("addBattery dev:", dev) - if !powersupply.IsSystemBattery(dev) { - return nil, false - } - - sysfsPath := dev.GetSysfsPath() - logger.Debug(sysfsPath) - - m.batteriesMu.Lock() - bat, ok := m.batteries[sysfsPath] - m.batteriesMu.Unlock() - if ok { - logger.Debugf("add battery failed , sysfsPath exists %q", sysfsPath) - bat.Refresh() - return bat, false - } - - bat = newBattery(m, dev) - if bat == nil { - logger.Debugf("add batteries failed, sysfsPath %q, new battery failed", sysfsPath) - return nil, false - } - - m.batteriesMu.Lock() - m.batteries[sysfsPath] = bat - m.refreshBatteryDisplay() - m.batteriesMu.Unlock() - bat.setRefreshDoneCallback(m.refreshBatteryDisplay) - return bat, true -} - -// removeBattery remove the battery from Manager.batteries, and stop export it. -func (m *Manager) removeBattery(dev *gudev.Device) { - sysfsPath := dev.GetSysfsPath() - - m.batteriesMu.Lock() - bat, ok := m.batteries[sysfsPath] - m.batteriesMu.Unlock() - - if ok { - logger.Info("removeBattery", sysfsPath) - m.batteriesMu.Lock() - delete(m.batteries, sysfsPath) - m.refreshBatteryDisplay() - m.batteriesMu.Unlock() - - err := m.service.StopExport(bat) - if err != nil { - logger.Warning(err) - } - m.emitBatteryRemoved(bat) - - bat.destroy() - } else { - logger.Warning("removeBattery failed: invalid sysfsPath ", sysfsPath) - } -} - -func (m *Manager) emitBatteryAdded(bat *Battery) { - err := m.service.Emit(m, "BatteryAdded", bat.getObjPath()) - if err != nil { - logger.Warning(err) - } -} - -func (m *Manager) emitBatteryRemoved(bat *Battery) { - err := m.service.Emit(m, "BatteryRemoved", bat.getObjPath()) - if err != nil { - logger.Warning(err) - } -} - -func (m *Manager) destroy() { - logger.Debug("destroy") - m.batteriesMu.Lock() - for _, bat := range m.batteries { - bat.destroy() - } - m.batteries = nil - m.batteriesMu.Unlock() - - if m.gudevClient != nil { - m.gudevClient.Unref() - m.gudevClient = nil - } - m.systemSigLoop.Stop() -} - -const configFile = "/var/lib/dde-daemon/power/config.json" - -type Config struct { - PowerSavingModeEnabled bool - PowerSavingModeAuto bool - PowerSavingModeAutoWhenBatteryLow bool - PowerSavingModeBrightnessDropPercent uint32 - PowerSavingModeAutoBatteryPercent uint32 - Mode string -} - -func loadConfig() (*Config, error) { - content, err := ioutil.ReadFile(configFile) - if err != nil { - return nil, err - } - var cfg Config - err = json.Unmarshal(content, &cfg) - if err != nil { - return nil, err - } - - return &cfg, nil -} - -func loadConfigSafe() *Config { - cfg, err := loadConfig() - if err != nil { - // ignore not exist error - if !os.IsNotExist(err) { - logger.Warning(err) - } - return nil - } - // 新增字段后第一次启动时,缺少两个新增字段的json,导致亮度下降百分比字段默认为0,导致与默认值不符,需要处理 - // 低电量自动待机字段的默认值为false,不会导致错误影响 - // 正常情况下该字段范围为10-40,只有在该情况下会出现0的可能 - if cfg.PowerSavingModeBrightnessDropPercent == 0 { - cfg.PowerSavingModeBrightnessDropPercent = 20 - } - - // when PowerSavingModeAutoBatteryPercent is lower than 10, it is not available, so change set it to 20 as default - if cfg.PowerSavingModeAutoBatteryPercent < 10 { - cfg.PowerSavingModeAutoBatteryPercent = 20 - } - - if cfg.Mode == "" { - cfg.Mode = ddeBalance - } - return cfg -} - -func (m *Manager) migrateFromCurrentConfigsToDsg() error { - err := m.saveDsgConfig("") - if err != nil { - logger.Warning("saveDsgConfig failed", err) - return err - } - - // 迁移完成后,删除本地配置文件 - err = os.Remove(configFile) - if err != nil { - logger.Warning("delete local configs file failed", err) - return err - } - - return nil -} - -func (m *Manager) saveDsgConfig(value string) (err error) { - switch value { - case "PowerSavingModeBrightnessDropPercent": - err = m.setDsgData(dsettingsPowerSavingModeBrightnessDropPercent, int64(m.PowerSavingModeBrightnessDropPercent), m.dsgPower) - if err != nil { - return err - } - case "PowerSavingModeAutoWhenBatteryLow": - err = m.setDsgData(dsettingsPowerSavingModeAutoWhenBatteryLow, m.PowerSavingModeAutoWhenBatteryLow, m.dsgPower) - if err != nil { - return err - } - case "PowerSavingModeAutoBatteryPercent": - err = m.setDsgData(dsettingsPowerSavingModeAutoBatteryPercent, int64(m.PowerSavingModeAutoBatteryPercent), m.dsgPower) - if err != nil { - return err - } - case "PowerSavingModeEnabled": - err = m.setDsgData(dsettingsPowerSavingModeEnabled, m.PowerSavingModeEnabled, m.dsgPower) - if err != nil { - return err - } - case "PowerSavingModeAuto": - err = m.setDsgData(dsettingsPowerSavingModeAuto, m.PowerSavingModeAuto, m.dsgPower) - if err != nil { - return err - } - case "": - err = m.setDsgData(dsettingsPowerSavingModeBrightnessDropPercent, int64(m.PowerSavingModeBrightnessDropPercent), m.dsgPower) - if err != nil { - return err - } - err = m.setDsgData(dsettingsPowerSavingModeAutoWhenBatteryLow, m.PowerSavingModeAutoWhenBatteryLow, m.dsgPower) - if err != nil { - return err - } - err = m.setDsgData(dsettingsPowerSavingModeAutoBatteryPercent, int64(m.PowerSavingModeAutoBatteryPercent), m.dsgPower) - if err != nil { - return err - } - err = m.setDsgData(dsettingsPowerSavingModeEnabled, m.PowerSavingModeEnabled, m.dsgPower) - if err != nil { - return err - } - err = m.setDsgData(dsettingsPowerSavingModeAuto, m.PowerSavingModeAuto, m.dsgPower) - if err != nil { - return err - } - } - - return m.setDsgData(dsettingsMode, m.Mode, m.dsgPower) -} - -func (m *Manager) setTlpMode(mode string) error { - logger.Info(" setTlpMode, mode : ", mode) - if m.TlpMode == mode { - return errors.New("repeat set tlp mode") - } - if !_validPowerModeArray.Contains(mode) { - return fmt.Errorf("PowerMode %q mode is not supported", mode) - } - if mode == ddePowerSave && m.batteryLow { - mode = ddeLowBattery - } - go m.setDSPCState(_powerConfigMap[mode].DSPCConfig) - return nil -} - -func (m *Manager) getShortIdleEnable() bool { - m.shortIdleEnableMu.RLock() - defer m.shortIdleEnableMu.RUnlock() - return m.shortIdleEnable -} - -func (m *Manager) setShortIdleEnable(enabled bool) { - m.shortIdleEnableMu.Lock() - m.shortIdleEnable = enabled - m.shortIdleEnableMu.Unlock() -} - -func (m *Manager) getShortIdleState() bool { - m.ShortIdleStateMu.RLock() - defer m.ShortIdleStateMu.RUnlock() - return m.ShortIdleState -} - -//仅对性能模式做设置,不记录状态 -//deepin-power-control idle wifi -func (m *Manager) setShortIdleState(state bool) error { - logger.Info(" setShortIdleState state : ", state) - if !m.getShortIdleEnable() { - logger.Info("System not open dsg of shortIdleEnable.") - return nil - } - - m.ShortIdleStateMu.Lock() - defer m.ShortIdleStateMu.Unlock() - - if m.ShortIdleState != state { - m.ShortIdleState = state - if m.dsgPower != nil { - err := m.setDsgData(dsettingsShortIdleState, state, m.dsgPower) - if err != nil { - logger.Warning(err) - } - } - } else { - logger.Info("setShortIdleState the same state : ", state) - return nil - } - - // 进入短idle: - // 1. deepin-power-control idle wifi on : 执行 `wifi on` 时,启动后台守护进程,开始监测无线网卡流量并在空闲时启用节能 - // 2. 电源模式切换为节能模式 - // 3. 进入短idle时,如果电量<=20%,则设置节能模式为lowBattery,否则为powersave - wifiState := shortIdleWifiOn - powerState := ddePowerSave - if m.batteryLow { - powerState = ddeLowBattery - } - if !state { - // 退出短idle: - // 1. deepin-power-control idle wifi off : 执行 `wifi off` 时,停止守护进程,恢复网卡默认行为 - // 2. 电源模式切换为节能模式 - // 3. 退出短idle时,如果电量<=20%,此时如果Mode为节能模式,则设置tlp模式为lowBattery,否则为powersave - wifiState = shortIdleWifiOff - - if m.Mode == ddePowerSave && m.batteryLow { - powerState = ddeLowBattery - } else { - powerState = m.Mode - } - } - go func() { - // 设置电源模式,仅设置tlp,不记录 - m.setDSPCState(_powerConfigMap[powerState].DSPCConfig) - - // 设置wifi短idle模式 - m.setDPCWifiState(wifiState) - }() - return nil -} - -func (m *Manager) doSetMode(mode string) { - logger.Info(" doSetMode, mode : ", mode) - if !_validPowerModeArray.Contains(mode) { - logger.Errorf("PowerMode %q mode is not supported", mode) - return - } - if mode == ddePowerSave && m.batteryLow { - mode = ddeLowBattery - } - fixMode := mode - if fixMode == ddeLowBattery { - fixMode = ddePowerSave - m.isLowBatteryMode = true - } else { - m.isLowBatteryMode = false - } - modeChanged := m.setPropMode(fixMode) - if modeChanged { - logger.Info("Set power mode", fixMode) - } - - // 处理ddeLowBattery情况,所以每次都要设置 - go m.setDSPCState(_powerConfigMap[mode].DSPCConfig) // doSetMode - m.setPropPowerSavingModeEnabled(_powerConfigMap[mode].PowerSavingModeEnabled) - - if m.lastMode != mode && mode != ddePowerSave && mode != ddeLowBattery { - m.lastMode = mode - } - if modeChanged { - _ = m.setDsgData(dsettingsMode, fixMode, m.dsgPower) - } - - logger.Info(" doSetMode, shortIdleState : ", m.getShortIdleState()) - // 如果恢复性能模式时,当前处于短idle状态,则需要恢复模式后,将TlpMode设置为节能模式 - // 在延时回调中重新检查短idle状态,避免在延时期间短idle退出后,错误地恢复节能模式 - if m.getShortIdleState() { - // 连续两次调用deepin-power-control,有概率会设置失败,因此使用延时500ms - time.AfterFunc(500*time.Millisecond, func() { - if !m.getShortIdleState() { - logger.Info("shortIdle state has changed, skip restoring power save mode") - return - } - err := m.setTlpMode(ddePowerSave) - if err != nil { - logger.Warning(err) - } - }) - } -} - -// 需求: 为了提高启动速度,登录前将性能模式设置为performance -// ① 为了减小耦合性,仅写文件(doSetCpuGovernor),不修改后端相关属性 -func (m *Manager) enablePerformanceInBoot() bool { - if m.Mode == ddePerformance { - m.updatePowerMode(true) - return false - } - displaySessions, err := m.displayManager.Sessions().Get(0) - if err != nil { - logger.Warning(err) - } else if len(displaySessions) > 0 { - return false - } - go m.setDSPCState(DSPCPerformance) - logger.Info("enablePerformanceInBoot performance") - return true -} diff --git a/system/power1/manager_ifc.go b/system/power1/manager_ifc.go deleted file mode 100644 index 2b6ae192d..000000000 --- a/system/power1/manager_ifc.go +++ /dev/null @@ -1,154 +0,0 @@ -// SPDX-FileCopyrightText: 2018 - 2026 UnionTech Software Technology Co., Ltd. -// -// SPDX-License-Identifier: GPL-3.0-or-later - -package power - -import ( - "errors" - "fmt" - - dbus "github.com/godbus/dbus/v5" - "github.com/linuxdeepin/dde-daemon/securityloader" - - "github.com/linuxdeepin/go-lib/dbusutil" -) - -const ( - dbusServiceName = "org.deepin.dde.Power1" - dbusPath = "/org/deepin/dde/Power1" - dbusInterface = dbusServiceName -) - -func (*Manager) GetInterfaceName() string { - return dbusInterface -} - -func (m *Manager) GetBatteries() (batteries []dbus.ObjectPath, busErr *dbus.Error) { - m.batteriesMu.Lock() - - batteries = make([]dbus.ObjectPath, len(m.batteries)) - idx := 0 - for _, bat := range m.batteries { - batteries[idx] = bat.getObjPath() - idx++ - } - - m.batteriesMu.Unlock() - return batteries, nil -} - -func (m *Manager) refreshBatteries() { - logger.Debug("RefreshBatteries") - m.batteriesMu.Lock() - for _, bat := range m.batteries { - bat.Refresh() - } - m.batteriesMu.Unlock() -} - -func (m *Manager) RefreshBatteries() *dbus.Error { - m.refreshBatteries() - return nil -} - -func (m *Manager) RefreshMains() *dbus.Error { - logger.Debug("RefreshMains") - if m.ac == nil { - return nil - } - - device := m.ac.newDevice() - if device == nil { - logger.Warning("RefreshMains: ac.newDevice failed") - return nil - } - m.refreshAC(device) - return nil -} - -func (m *Manager) Refresh() *dbus.Error { - err := m.RefreshMains() - if err != nil { - return err - } - err = m.RefreshBatteries() - if err != nil { - return err - } - return nil -} - -func (m *Manager) SetCpuBoost(enabled bool) *dbus.Error { - m.setPropCpuBoost(enabled) - return nil -} - -func (m *Manager) SetCpuGovernor(governor string) *dbus.Error { - m.setPropCpuGovernor(governor) - return nil -} - -func (m *Manager) SetMode(mode string) *dbus.Error { - if m.Mode == mode { - return dbusutil.ToError(errors.New("repeat set mode")) - } - logger.Info(" SetMode mode : ", mode) - if !_validPowerModeArray.Contains(mode) { - return dbusutil.ToError(fmt.Errorf("PowerMode %q mode is not supported", mode)) - } - - // 手动(外部请求)切换到节能模式,或节能模式切换到其他模式时,关闭电池自动节能和低电量自动节能 - if ddePowerSave == m.Mode || ddePowerSave == mode { - m.PropsMu.Lock() - m.updatePowerSavingState(false) - m.PropsMu.Unlock() - } - m.doSetMode(mode) - return nil -} - -func (m *Manager) SetAllowCaller(sender dbus.Sender, uniqueName string) *dbus.Error { - return dbusutil.ToError(m.allowCallers.AddCaller(securityloader.PowerScope, sender, uniqueName)) -} - -func (m *Manager) SetTlpMode(sender dbus.Sender, mode string) *dbus.Error { - err := securityloader.AuthorizeWithPolkit( - m.allowCallers, - securityloader.PowerScope, - sender, - m.service.Conn(), - "org.deepin.dde.power.doAction", - ) - if err != nil { - logger.Warningf("SetTlpMode authorization failed: %q", err.Error()) - return dbusutil.ToError(err) - } - logger.Info("SetTlpMode : ", mode) - return dbusutil.ToError(m.setTlpMode(mode)) -} - -func (m *Manager) LockCpuFreq(governor string, lockTime int32) *dbus.Error { - // TODO 改用tlp - // currentGovernor, err := m.cpus.GetGovernor() - // if err != nil { - // return dbusutil.ToError(err) - // } - // - // // change cpu governor - // if governor != currentGovernor { - // err = m.cpus.SetGovernor(governor, false) - // if err != nil { - // return dbusutil.ToError(err) - // } - // - // time.AfterFunc(time.Second*time.Duration(lockTime), func() { - // err := m.cpus.SetGovernor(currentGovernor, false) - // if err != nil { - // logger.Warningf("rewrite cpu scaling_governor file failed:%v", err) - // } - // }) - // } - - return nil -} diff --git a/system/power1/manager_powersave.go b/system/power1/manager_powersave.go deleted file mode 100644 index 3eaf503d8..000000000 --- a/system/power1/manager_powersave.go +++ /dev/null @@ -1,153 +0,0 @@ -// SPDX-FileCopyrightText: 2026 UnionTech Software Technology Co., Ltd. -// -// SPDX-License-Identifier: GPL-3.0-or-later - -package power - -import ( - dbus "github.com/godbus/dbus/v5" - "github.com/linuxdeepin/dde-daemon/common/systemdunit" -) - -type DSPCMode string - -const ( - DSPCPerformance DSPCMode = "performance" - DSPCBalance DSPCMode = "balance" - DSPCSaving DSPCMode = "saving" - DSPCLowBattery DSPCMode = "lowbat" -) - -type powerConfig struct { - DSPCConfig DSPCMode - - PowerSavingModeEnabled bool -} - -// TODO dconfig 或其他配置存储 -var _powerConfigMap = map[string]*powerConfig{ - ddePerformance: { - DSPCConfig: DSPCPerformance, - PowerSavingModeEnabled: false, - }, - ddeBalance: { - DSPCConfig: DSPCBalance, - PowerSavingModeEnabled: false, - }, - ddePowerSave: { - DSPCConfig: DSPCSaving, - PowerSavingModeEnabled: true, - }, - ddeLowBattery: { - DSPCConfig: DSPCLowBattery, - PowerSavingModeEnabled: true, - }, -} - -func (m *Manager) setDPCWifiState(state string) error { - logger.Infof("setDPCWifiState, state: %s", state) - m.dspcMu.Lock() - defer m.dspcMu.Unlock() - conn, err := dbus.SystemBus() - if err != nil { - logger.Warning("Failed to connect to system bus:", err) - return err - } - - unitName := "dde-system-power-control-wifi.service" - unitInfo := systemdunit.TransientUnit{ - Dbus: conn, - UnitName: unitName, - Type: "oneshot", - Description: "Transient Unit set deepin power control wifi state", - Environment: []string{}, - Commands: []string{"/usr/sbin/deepin-power-control", "idle", "wifi", state}, - } - err = unitInfo.StartTransientUnit() - if err != nil { - logger.Warningf("failed create unit: %v, err: %v", unitName, err) - return err - } - if !unitInfo.WaitforFinish(m.systemSigLoop) { - logger.Warningf("%v run failed", unitName) - return err - } - return nil -} - -func (m *Manager) setDSPCState(state DSPCMode) { - logger.Infof("setDSPCState, state: %s", state) - m.dspcMu.Lock() - defer m.dspcMu.Unlock() - conn, err := dbus.SystemBus() - if err != nil { - logger.Warning("Failed to connect to system bus:", err) - return - } - - unitName := "dde-system-power-control.service" - unitInfo := systemdunit.TransientUnit{ - Dbus: conn, - UnitName: unitName, - Type: "oneshot", - Description: "Transient Unit set deepin system power control", - Environment: []string{}, - Commands: []string{"/usr/sbin/deepin-power-control", "set", string(state)}, - } - err = unitInfo.StartTransientUnit() - if err != nil { - logger.Warningf("failed create unit: %v, err: %v", unitName, err) - return - } - if !unitInfo.WaitforFinish(m.systemSigLoop) { - logger.Warningf("%v run failed", unitName) - return - } -} - -// 关联电量、电源连接状态、低电量节能开关、使用电池节能开关四项状态的变动,修改系统的功耗模式 -func (m *Manager) updatePowerMode(init bool) { - logger.Info("start updatePowerMode") - if !m.initDone { - // 初始化未完成时,暂不提供功能 - return - } - var enablePowerSave bool - var enableLowPower bool - m.PropsMu.Lock() - defer m.PropsMu.Unlock() - if m.PowerSavingModeAuto && m.OnBattery { - enablePowerSave = true - } - - if m.PowerSavingModeAutoWhenBatteryLow && m.batteryLow { - enableLowPower = true - } - logger.Infof("PowerSavingModeAuto: %v\n OnBattery:%v \n PowerSavingModeAutoWhenBatteryLow:%v \n batteryLow:%v \n", - m.PowerSavingModeAuto, m.OnBattery, m.PowerSavingModeAutoWhenBatteryLow, m.batteryLow) - logger.Infof("lastMode: %v, ShortIdleState : %v", m.lastMode, m.getShortIdleState()) - if !m.PowerSavingModeAuto && !m.PowerSavingModeAutoWhenBatteryLow && !init { - return - } - mode := m.lastMode - if init { - mode = m.Mode - } - if enablePowerSave { - mode = ddePowerSave - } - if enableLowPower { - mode = ddeLowBattery - } - m.doSetMode(mode) -} - -func (m *Manager) updatePowerSavingState(state bool) { - if m.setPropPowerSavingModeAutoWhenBatteryLow(state) { - _ = m.setDsgData(dsettingsPowerSavingModeAutoWhenBatteryLow, state, m.dsgPower) - } - - if m.setPropPowerSavingModeAuto(state) { - _ = m.setDsgData(dsettingsPowerSavingModeAuto, state, m.dsgPower) - } -} diff --git a/system/power1/power_dbusutil.go b/system/power1/power_dbusutil.go deleted file mode 100644 index eb4f78302..000000000 --- a/system/power1/power_dbusutil.go +++ /dev/null @@ -1,514 +0,0 @@ -// Code generated by "dbusutil-gen -type Manager,Battery -import github.com/linuxdeepin/dde-api/powersupply/battery manager.go battery.go"; DO NOT EDIT. - -package power - -import ( - "github.com/linuxdeepin/dde-api/powersupply/battery" -) - -func (v *Manager) setPropOnBattery(value bool) (changed bool) { - if v.OnBattery != value { - v.OnBattery = value - v.emitPropChangedOnBattery(value) - return true - } - return false -} - -func (v *Manager) emitPropChangedOnBattery(value bool) error { - return v.service.EmitPropertyChanged(v, "OnBattery", value) -} - -func (v *Manager) setPropHasLidSwitch(value bool) (changed bool) { - if v.HasLidSwitch != value { - v.HasLidSwitch = value - v.emitPropChangedHasLidSwitch(value) - return true - } - return false -} - -func (v *Manager) emitPropChangedHasLidSwitch(value bool) error { - return v.service.EmitPropertyChanged(v, "HasLidSwitch", value) -} - -func (v *Manager) setPropHasBattery(value bool) (changed bool) { - if v.HasBattery != value { - v.HasBattery = value - v.emitPropChangedHasBattery(value) - return true - } - return false -} - -func (v *Manager) emitPropChangedHasBattery(value bool) error { - return v.service.EmitPropertyChanged(v, "HasBattery", value) -} - -func (v *Manager) setPropBatteryPercentage(value float64) (changed bool) { - if v.BatteryPercentage != value { - v.BatteryPercentage = value - v.emitPropChangedBatteryPercentage(value) - return true - } - return false -} - -func (v *Manager) emitPropChangedBatteryPercentage(value float64) error { - return v.service.EmitPropertyChanged(v, "BatteryPercentage", value) -} - -func (v *Manager) setPropBatteryStatus(value battery.Status) (changed bool) { - if v.BatteryStatus != value { - v.BatteryStatus = value - v.emitPropChangedBatteryStatus(value) - return true - } - return false -} - -func (v *Manager) emitPropChangedBatteryStatus(value battery.Status) error { - return v.service.EmitPropertyChanged(v, "BatteryStatus", value) -} - -func (v *Manager) setPropBatteryTimeToEmpty(value uint64) (changed bool) { - if v.BatteryTimeToEmpty != value { - v.BatteryTimeToEmpty = value - v.emitPropChangedBatteryTimeToEmpty(value) - return true - } - return false -} - -func (v *Manager) emitPropChangedBatteryTimeToEmpty(value uint64) error { - return v.service.EmitPropertyChanged(v, "BatteryTimeToEmpty", value) -} - -func (v *Manager) setPropBatteryTimeToFull(value uint64) (changed bool) { - if v.BatteryTimeToFull != value { - v.BatteryTimeToFull = value - v.emitPropChangedBatteryTimeToFull(value) - return true - } - return false -} - -func (v *Manager) emitPropChangedBatteryTimeToFull(value uint64) error { - return v.service.EmitPropertyChanged(v, "BatteryTimeToFull", value) -} - -func (v *Manager) setPropBatteryCapacity(value float64) (changed bool) { - if v.BatteryCapacity != value { - v.BatteryCapacity = value - v.emitPropChangedBatteryCapacity(value) - return true - } - return false -} - -func (v *Manager) emitPropChangedBatteryCapacity(value float64) error { - return v.service.EmitPropertyChanged(v, "BatteryCapacity", value) -} - -func (v *Manager) setPropPowerSavingModeEnabled(value bool) (changed bool) { - if v.PowerSavingModeEnabled != value { - v.PowerSavingModeEnabled = value - v.emitPropChangedPowerSavingModeEnabled(value) - return true - } - return false -} - -func (v *Manager) emitPropChangedPowerSavingModeEnabled(value bool) error { - return v.service.EmitPropertyChanged(v, "PowerSavingModeEnabled", value) -} - -func (v *Manager) setPropPowerSavingModeAuto(value bool) (changed bool) { - if v.PowerSavingModeAuto != value { - v.PowerSavingModeAuto = value - v.emitPropChangedPowerSavingModeAuto(value) - return true - } - return false -} - -func (v *Manager) emitPropChangedPowerSavingModeAuto(value bool) error { - return v.service.EmitPropertyChanged(v, "PowerSavingModeAuto", value) -} - -func (v *Manager) setPropPowerSavingModeAutoWhenBatteryLow(value bool) (changed bool) { - if v.PowerSavingModeAutoWhenBatteryLow != value { - v.PowerSavingModeAutoWhenBatteryLow = value - v.emitPropChangedPowerSavingModeAutoWhenBatteryLow(value) - return true - } - return false -} - -func (v *Manager) emitPropChangedPowerSavingModeAutoWhenBatteryLow(value bool) error { - return v.service.EmitPropertyChanged(v, "PowerSavingModeAutoWhenBatteryLow", value) -} - -func (v *Manager) setPropPowerSavingModeBrightnessDropPercent(value uint32) (changed bool) { - if v.PowerSavingModeBrightnessDropPercent != value { - v.PowerSavingModeBrightnessDropPercent = value - v.emitPropChangedPowerSavingModeBrightnessDropPercent(value) - return true - } - return false -} - -func (v *Manager) emitPropChangedPowerSavingModeBrightnessDropPercent(value uint32) error { - return v.service.EmitPropertyChanged(v, "PowerSavingModeBrightnessDropPercent", value) -} - -func (v *Manager) setPropPowerSavingModeAutoBatteryPercent(value uint32) (changed bool) { - if v.PowerSavingModeAutoBatteryPercent != value { - v.PowerSavingModeAutoBatteryPercent = value - v.emitPropChangedPowerSavingModeAutoBatteryPercent(value) - return true - } - return false -} - -func (v *Manager) emitPropChangedPowerSavingModeAutoBatteryPercent(value uint32) error { - return v.service.EmitPropertyChanged(v, "PowerSavingModeAutoBatteryPercent", value) -} - -func (v *Manager) setPropPowerSavingModeBrightnessData(value string) (changed bool) { - if v.PowerSavingModeBrightnessData != value { - v.PowerSavingModeBrightnessData = value - v.emitPropChangedPowerSavingModeBrightnessData(value) - return true - } - return false -} - -func (v *Manager) emitPropChangedPowerSavingModeBrightnessData(value string) error { - return v.service.EmitPropertyChanged(v, "PowerSavingModeBrightnessData", value) -} - -func (v *Manager) setPropCpuGovernor(value string) (changed bool) { - if v.CpuGovernor != value { - v.CpuGovernor = value - v.emitPropChangedCpuGovernor(value) - return true - } - return false -} - -func (v *Manager) emitPropChangedCpuGovernor(value string) error { - return v.service.EmitPropertyChanged(v, "CpuGovernor", value) -} - -func (v *Manager) setPropCpuBoost(value bool) (changed bool) { - if v.CpuBoost != value { - v.CpuBoost = value - v.emitPropChangedCpuBoost(value) - return true - } - return false -} - -func (v *Manager) emitPropChangedCpuBoost(value bool) error { - return v.service.EmitPropertyChanged(v, "CpuBoost", value) -} - -func (v *Manager) setPropIsHighPerformanceSupported(value bool) (changed bool) { - if v.IsHighPerformanceSupported != value { - v.IsHighPerformanceSupported = value - v.emitPropChangedIsHighPerformanceSupported(value) - return true - } - return false -} - -func (v *Manager) emitPropChangedIsHighPerformanceSupported(value bool) error { - return v.service.EmitPropertyChanged(v, "IsHighPerformanceSupported", value) -} - -func (v *Manager) setPropIsBalanceSupported(value bool) (changed bool) { - if v.IsBalanceSupported != value { - v.IsBalanceSupported = value - v.emitPropChangedIsBalanceSupported(value) - return true - } - return false -} - -func (v *Manager) emitPropChangedIsBalanceSupported(value bool) error { - return v.service.EmitPropertyChanged(v, "IsBalanceSupported", value) -} - -func (v *Manager) setPropIsPowerSaveSupported(value bool) (changed bool) { - if v.IsPowerSaveSupported != value { - v.IsPowerSaveSupported = value - v.emitPropChangedIsPowerSaveSupported(value) - return true - } - return false -} - -func (v *Manager) emitPropChangedIsPowerSaveSupported(value bool) error { - return v.service.EmitPropertyChanged(v, "IsPowerSaveSupported", value) -} - -func (v *Manager) setPropSupportSwitchPowerMode(value bool) (changed bool) { - if v.SupportSwitchPowerMode != value { - v.SupportSwitchPowerMode = value - v.emitPropChangedSupportSwitchPowerMode(value) - return true - } - return false -} - -func (v *Manager) emitPropChangedSupportSwitchPowerMode(value bool) error { - return v.service.EmitPropertyChanged(v, "SupportSwitchPowerMode", value) -} - -func (v *Manager) setPropMode(value string) (changed bool) { - if v.Mode != value { - v.Mode = value - v.emitPropChangedMode(value) - return true - } - return false -} - -func (v *Manager) emitPropChangedMode(value string) error { - return v.service.EmitPropertyChanged(v, "Mode", value) -} - -func (v *Battery) setPropSysfsPath(value string) (changed bool) { - if v.SysfsPath != value { - v.SysfsPath = value - v.emitPropChangedSysfsPath(value) - return true - } - return false -} - -func (v *Battery) emitPropChangedSysfsPath(value string) error { - return v.service.EmitPropertyChanged(v, "SysfsPath", value) -} - -func (v *Battery) setPropIsPresent(value bool) (changed bool) { - if v.IsPresent != value { - v.IsPresent = value - v.emitPropChangedIsPresent(value) - return true - } - return false -} - -func (v *Battery) emitPropChangedIsPresent(value bool) error { - return v.service.EmitPropertyChanged(v, "IsPresent", value) -} - -func (v *Battery) setPropManufacturer(value string) (changed bool) { - if v.Manufacturer != value { - v.Manufacturer = value - v.emitPropChangedManufacturer(value) - return true - } - return false -} - -func (v *Battery) emitPropChangedManufacturer(value string) error { - return v.service.EmitPropertyChanged(v, "Manufacturer", value) -} - -func (v *Battery) setPropModelName(value string) (changed bool) { - if v.ModelName != value { - v.ModelName = value - v.emitPropChangedModelName(value) - return true - } - return false -} - -func (v *Battery) emitPropChangedModelName(value string) error { - return v.service.EmitPropertyChanged(v, "ModelName", value) -} - -func (v *Battery) setPropSerialNumber(value string) (changed bool) { - if v.SerialNumber != value { - v.SerialNumber = value - v.emitPropChangedSerialNumber(value) - return true - } - return false -} - -func (v *Battery) emitPropChangedSerialNumber(value string) error { - return v.service.EmitPropertyChanged(v, "SerialNumber", value) -} - -func (v *Battery) setPropName(value string) (changed bool) { - if v.Name != value { - v.Name = value - v.emitPropChangedName(value) - return true - } - return false -} - -func (v *Battery) emitPropChangedName(value string) error { - return v.service.EmitPropertyChanged(v, "Name", value) -} - -func (v *Battery) setPropTechnology(value string) (changed bool) { - if v.Technology != value { - v.Technology = value - v.emitPropChangedTechnology(value) - return true - } - return false -} - -func (v *Battery) emitPropChangedTechnology(value string) error { - return v.service.EmitPropertyChanged(v, "Technology", value) -} - -func (v *Battery) setPropEnergy(value float64) (changed bool) { - if v.Energy != value { - v.Energy = value - v.emitPropChangedEnergy(value) - return true - } - return false -} - -func (v *Battery) emitPropChangedEnergy(value float64) error { - return v.service.EmitPropertyChanged(v, "Energy", value) -} - -func (v *Battery) setPropEnergyFull(value float64) (changed bool) { - if v.EnergyFull != value { - v.EnergyFull = value - v.emitPropChangedEnergyFull(value) - return true - } - return false -} - -func (v *Battery) emitPropChangedEnergyFull(value float64) error { - return v.service.EmitPropertyChanged(v, "EnergyFull", value) -} - -func (v *Battery) setPropEnergyFullDesign(value float64) (changed bool) { - if v.EnergyFullDesign != value { - v.EnergyFullDesign = value - v.emitPropChangedEnergyFullDesign(value) - return true - } - return false -} - -func (v *Battery) emitPropChangedEnergyFullDesign(value float64) error { - return v.service.EmitPropertyChanged(v, "EnergyFullDesign", value) -} - -func (v *Battery) setPropEnergyRate(value float64) (changed bool) { - if v.EnergyRate != value { - v.EnergyRate = value - v.emitPropChangedEnergyRate(value) - return true - } - return false -} - -func (v *Battery) emitPropChangedEnergyRate(value float64) error { - return v.service.EmitPropertyChanged(v, "EnergyRate", value) -} - -func (v *Battery) setPropVoltage(value float64) (changed bool) { - if v.Voltage != value { - v.Voltage = value - v.emitPropChangedVoltage(value) - return true - } - return false -} - -func (v *Battery) emitPropChangedVoltage(value float64) error { - return v.service.EmitPropertyChanged(v, "Voltage", value) -} - -func (v *Battery) setPropPercentage(value float64) (changed bool) { - if v.Percentage != value { - v.Percentage = value - v.emitPropChangedPercentage(value) - return true - } - return false -} - -func (v *Battery) emitPropChangedPercentage(value float64) error { - return v.service.EmitPropertyChanged(v, "Percentage", value) -} - -func (v *Battery) setPropCapacity(value float64) (changed bool) { - if v.Capacity != value { - v.Capacity = value - v.emitPropChangedCapacity(value) - return true - } - return false -} - -func (v *Battery) emitPropChangedCapacity(value float64) error { - return v.service.EmitPropertyChanged(v, "Capacity", value) -} - -func (v *Battery) setPropStatus(value battery.Status) (changed bool) { - if v.Status != value { - v.Status = value - v.emitPropChangedStatus(value) - return true - } - return false -} - -func (v *Battery) emitPropChangedStatus(value battery.Status) error { - return v.service.EmitPropertyChanged(v, "Status", value) -} - -func (v *Battery) setPropTimeToEmpty(value uint64) (changed bool) { - if v.TimeToEmpty != value { - v.TimeToEmpty = value - v.emitPropChangedTimeToEmpty(value) - return true - } - return false -} - -func (v *Battery) emitPropChangedTimeToEmpty(value uint64) error { - return v.service.EmitPropertyChanged(v, "TimeToEmpty", value) -} - -func (v *Battery) setPropTimeToFull(value uint64) (changed bool) { - if v.TimeToFull != value { - v.TimeToFull = value - v.emitPropChangedTimeToFull(value) - return true - } - return false -} - -func (v *Battery) emitPropChangedTimeToFull(value uint64) error { - return v.service.EmitPropertyChanged(v, "TimeToFull", value) -} - -func (v *Battery) setPropUpdateTime(value int64) (changed bool) { - if v.UpdateTime != value { - v.UpdateTime = value - v.emitPropChangedUpdateTime(value) - return true - } - return false -} - -func (v *Battery) emitPropChangedUpdateTime(value int64) error { - return v.service.EmitPropertyChanged(v, "UpdateTime", value) -} diff --git a/system/power1/power_key_edit.go b/system/power1/power_key_edit.go deleted file mode 100644 index a5bb44e28..000000000 --- a/system/power1/power_key_edit.go +++ /dev/null @@ -1,38 +0,0 @@ -// SPDX-FileCopyrightText: 2018 - 2022 UnionTech Software Technology Co., Ltd. -// -// SPDX-License-Identifier: GPL-3.0-or-later - -package power - -import ( - "errors" - - "github.com/linuxdeepin/dde-daemon/common/dconfig" - "github.com/linuxdeepin/go-lib/utils" -) - -func interfaceToArrayString(v interface{}) (d []interface{}) { - if utils.IsInterfaceNil(v) { - return - } - - d, ok := v.([]interface{}) - if !ok { - logger.Errorf("interfaceToArrayString() failed: %#v", v) - return - } - return -} - -func (m *Manager) setDsgData(key string, value interface{}, dsg *dconfig.DConfig) error { - if dsg == nil { - return errors.New("setDsgData dsg is nil") - } - err := dsg.SetValue(key, value) - if err != nil { - logger.Warningf("setDsgData key : %s. err : %v", key, err) - return err - } - logger.Debugf("setDsgData key : %s , value : %v", key, value) - return nil -} diff --git a/system/power1/power_key_edit_test.go b/system/power1/power_key_edit_test.go deleted file mode 100644 index f81cb7d64..000000000 --- a/system/power1/power_key_edit_test.go +++ /dev/null @@ -1,33 +0,0 @@ -// SPDX-FileCopyrightText: 2018 - 2022 UnionTech Software Technology Co., Ltd. -// -// SPDX-License-Identifier: GPL-3.0-or-later - -package power - -import ( - "testing" - - "github.com/stretchr/testify/assert" -) - -func Test_interfaceToArrayString(t *testing.T) { - data := []struct { - test interface{} - result []string - }{ - {[]interface{}{}, []string{}}, - {[]interface{}{"0"}, []string{"0"}}, - {[]interface{}{"0", "1"}, []string{"0", "1"}}, - {[]interface{}{"0", "1", "2"}, []string{"0", "1", "2"}}, - {[]interface{}{"0", "1", "2", "3"}, []string{"0", "1", "2", "3"}}, - } - for _, d := range data { - trans := interfaceToArrayString(d.test) - arr := make([]string, len(trans)) - for i, v := range trans { - arr[i] = v.(string) - } - - assert.Equal(t, arr, d.result) - } -} diff --git a/system/power1/power_test.go b/system/power1/power_test.go deleted file mode 100644 index 7e6359034..000000000 --- a/system/power1/power_test.go +++ /dev/null @@ -1,57 +0,0 @@ -// SPDX-FileCopyrightText: 2018 - 2026 UnionTech Software Technology Co., Ltd. -// -// SPDX-License-Identifier: GPL-3.0-or-later - -package power - -import ( - "sync" - "testing" - - "github.com/godbus/dbus/v5" - "github.com/stretchr/testify/assert" -) - -func Test_getValidName(t *testing.T) { - names := []string{"BAT0", "test.t", "test:t", "test-t", "test.1:2-3.4:5-6"} - for _, name := range names { - path := dbus.ObjectPath("/battery_" + getValidName(name)) - t.Log(path) - assert.True(t, path.IsValid()) - } -} -func TestSetShortIdleStateDisabledIsNoOp(t *testing.T) { - m := new(Manager) - - if err := m.setShortIdleState(true); err != nil { - t.Fatalf("setShortIdleState returned error while disabled: %v", err) - } - if m.getShortIdleState() { - t.Fatal("short idle state changed while disabled") - } -} - -func TestShortIdleEnableConcurrentAccess(t *testing.T) { - m := new(Manager) - - var wg sync.WaitGroup - wg.Add(2) - go func() { - defer wg.Done() - for i := 0; i < 10000; i++ { - m.setShortIdleEnable(i%2 == 0) - } - }() - go func() { - defer wg.Done() - for i := 0; i < 10000; i++ { - _ = m.getShortIdleEnable() - } - }() - wg.Wait() - - m.setShortIdleEnable(true) - if !m.getShortIdleEnable() { - t.Fatal("short idle enable state was not updated") - } -} diff --git a/system/power1/testdata/scaling_available_governors b/system/power1/testdata/scaling_available_governors deleted file mode 100644 index 22a0a13d2..000000000 --- a/system/power1/testdata/scaling_available_governors +++ /dev/null @@ -1 +0,0 @@ -performance powersave \ No newline at end of file diff --git a/system/power1/testdata/scaling_governor b/system/power1/testdata/scaling_governor deleted file mode 100644 index 3c804e87a..000000000 --- a/system/power1/testdata/scaling_governor +++ /dev/null @@ -1 +0,0 @@ -performance \ No newline at end of file diff --git a/system/power1/testdata/scaling_governor2 b/system/power1/testdata/scaling_governor2 deleted file mode 100644 index e69de29bb..000000000 diff --git a/system/power1/testdata/setGovernor/scaling_governor b/system/power1/testdata/setGovernor/scaling_governor deleted file mode 100644 index 3c804e87a..000000000 --- a/system/power1/testdata/setGovernor/scaling_governor +++ /dev/null @@ -1 +0,0 @@ -performance \ No newline at end of file