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