From 538f692a973aa3cb17c1d000852b833c83f0e5ca Mon Sep 17 00:00:00 2001 From: lichangze Date: Wed, 16 Nov 2022 19:59:42 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20lastore=E6=A8=A1=E5=9D=97=E9=80=BB?= =?UTF-8?q?=E8=BE=91=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 原有逻辑: lastore的通知都是dde-session-daemon去监听com.deepin.lastore.Job的状态,持续监听占用资源,而且交互不方便. 逻辑优化: lastore-daemon定义一套agent接口,由dde-daemon的lastore模块实现相关接口并导出,需要发通知和需要获取系统代理时,lastore-daemon调用agent接口完成. Log: lastore模块逻辑修改 Task: https://pms.uniontech.com/task-view-214983.html Influence: 通知和apt代理获取 Change-Id: I27df48576528a5932e7263f3945e156dda53dc3b --- lastore/agent.go | 108 +++++++ lastore/agent_ifc.go | 96 ++++++ lastore/daemon.go | 56 ++-- lastore/exported_methods_auto.go | 16 +- lastore/lastore.go | 537 ++++--------------------------- lastore/notify.go | 43 +-- lastore/system.go | 51 --- lastore/tools.go | 74 ----- 8 files changed, 310 insertions(+), 671 deletions(-) create mode 100644 lastore/agent.go create mode 100644 lastore/agent_ifc.go delete mode 100644 lastore/system.go diff --git a/lastore/agent.go b/lastore/agent.go new file mode 100644 index 000000000..5072d3d58 --- /dev/null +++ b/lastore/agent.go @@ -0,0 +1,108 @@ +package lastore + +import ( + "github.com/godbus/dbus" + "sync" + + lastore "github.com/linuxdeepin/go-dbus-factory/com.deepin.lastore" + "github.com/linuxdeepin/go-lib/dbusutil" +) + +// lastore agent的interface name +const ( + sessionAgentInterface = "com.deepin.lastore.Agent" +) + +// 对应com.deepin.daemon.Network.GetProxy方法的key值 +const ( + proxyTypeHttp = "http" + proxyTypeHttps = "https" + proxyTypeFtp = "ftp" + proxyTypeSocks = "socks" +) + +// 对应系统代理环境变量 +const ( + envHttpProxy = "http_proxy" + envHttpsProxy = "https_proxy" + envFtpProxy = "ftp_proxy" + envAllProxy = "all_proxy" +) + +// lastoreNotifyType 通知类型 +type lastoreNotifyType string + +const ( + AutoCleanDone lastoreNotifyType = "AutoCleanDone" + AppRemove lastoreNotifyType = "AppRemove" + CanUpdate lastoreNotifyType = "CanUpdate" + AutoDownloading lastoreNotifyType = "AutoDownloading" + CanUpgrade lastoreNotifyType = "CanUpgrade" + UpgradeFailed lastoreNotifyType = "UpgradeFailed" +) + +// Status com.deepin.lastore.Job中的Status属性 +type Status string + +const ( + ReadyStatus Status = "ready" + RunningStatus Status = "running" + FailedStatus Status = "failed" + SucceedStatus Status = "succeed" + PausedStatus Status = "paused" + EndStatus Status = "end" +) + +// JobInfo com.deepin.lastore.Job中需要的属性 +type JobInfo struct { + Id string + Status Status + Name string + Progress float64 + Type string +} + +// Agent 需要实现GetManualProxy和SendNotify两个接口 +type Agent struct { + sysService *dbusutil.Service + lastoreObj *Lastore + sysLastore lastore.Lastore + mu sync.Mutex +} + +func newAgent(l *Lastore) (*Agent, error) { + sysBus, err := dbusutil.NewSystemService() + if err != nil { + logger.Warning(err) + return nil, err + } + a := &Agent{ + sysService: sysBus, + } + a.lastoreObj = l + a.sysLastore = lastore.NewLastore(a.sysService.Conn()) + return a, nil +} + +func (a *Agent) init() { + err := a.sysService.Export("/com/deepin/lastore/agent", a) + if err != nil { + logger.Warning(err) + return + } + err = a.sysLastore.Manager().RegisterAgent(0, "/com/deepin/lastore/agent") + if err != nil { + logger.Warning(err) + } +} + +func (a *Agent) destroy() { + err := a.sysLastore.Manager().UnRegisterAgent(0, "/com/deepin/lastore/agent") + if err != nil { + logger.Warning(err) + } +} + +func (a *Agent) checkCallerAuth(sender dbus.Sender) bool { + return false +} diff --git a/lastore/agent_ifc.go b/lastore/agent_ifc.go new file mode 100644 index 000000000..678d1ccea --- /dev/null +++ b/lastore/agent_ifc.go @@ -0,0 +1,96 @@ +package lastore + +import ( + "errors" + "fmt" + "strings" + + "github.com/godbus/dbus" + lastore "github.com/linuxdeepin/go-dbus-factory/com.deepin.lastore" + "github.com/linuxdeepin/go-lib/dbusutil" + "github.com/linuxdeepin/go-lib/gettext" +) + +func (*Agent) GetInterfaceName() string { + return sessionAgentInterface +} + +func (a *Agent) GetManualProxy(sender dbus.Sender) (map[string]string, *dbus.Error) { + // TODO 获取代理认证信息 + a.checkCallerAuth(sender) + method, err := a.lastoreObj.network.GetProxyMethod(0) + if err != nil { + logger.Warning(err) + return nil, dbusutil.ToError(err) + } + if method != "manual" { + return nil, dbusutil.ToError(errors.New("only support manual proxy")) + } + proxyTypeList := []string{ + proxyTypeHttp, proxyTypeHttps, proxyTypeFtp, + } + proxyEnvMap := make(map[string]string) + for _, typ := range proxyTypeList { + host, port, err := a.lastoreObj.network.GetProxy(0, typ) + if err != nil { + logger.Warning(err) + continue + } + proxyEnvMap[fmt.Sprintf("%s_proxy", typ)] = fmt.Sprintf("%s://%s:%s", proxyTypeHttp, host, port) + } + host, port, err := a.lastoreObj.network.GetProxy(0, proxyTypeSocks) + if err != nil { + logger.Warning(err) + return proxyEnvMap, dbusutil.ToError(err) + } + proxyEnvMap[envAllProxy] = fmt.Sprintf("%s://%s:%s", proxyTypeSocks, host, port) + return proxyEnvMap, nil +} + +func (a *Agent) SendNotify(sender dbus.Sender, typ lastoreNotifyType, jobPath dbus.ObjectPath, args []string) *dbus.Error { + a.checkCallerAuth(sender) + logger.Info("receive notify from lastore") + var jobInfo JobInfo + if jobPath != "" { + notifyJob, err := lastore.NewJob(a.sysService.Conn(), jobPath) + if err != nil { + logger.Warning(err) + return dbusutil.ToError(err) + } + + jobInfo.Id, _ = notifyJob.Id().Get(dbus.FlagNoAutoStart) + jobInfo.Type, _ = notifyJob.Type().Get(dbus.FlagNoAutoStart) + status, _ := notifyJob.Status().Get(dbus.FlagNoAutoStart) + jobInfo.Status = Status(status) + jobInfo.Name, _ = notifyJob.Name().Get(dbus.FlagNoAutoStart) + } + switch typ { + case AutoCleanDone: + a.lastoreObj.notifyAutoClean() + case AppRemove: + switch jobInfo.Status { + case FailedStatus: + a.lastoreObj.notifyRemove("", false, a.lastoreObj.createJobFailedActions(jobInfo.Id)) + case SucceedStatus: + a.lastoreObj.notifyRemove("", true, nil) + } + case CanUpdate: + if strings.Contains(jobInfo.Name, "+notify") { + a.lastoreObj.notifyUpdateSource(a.lastoreObj.createUpdateActions()) + } + case AutoDownloading: + msg := gettext.Tr("Auto Downloading") + a.lastoreObj.sendNotify("preferences-system", "", msg, a.lastoreObj.createUpdateActions(), nil, notifyExpireTimeoutDefault, "dde-control-center") + case CanUpgrade: + msg := gettext.Tr("Upgrade Available") + a.lastoreObj.sendNotify("preferences-system", "", msg, a.lastoreObj.createCanUpgradeActions(), nil, notifyExpireTimeoutDefault, "dde-control-center") + case UpgradeFailed: + // TODO 还需要失败的reason + msg := gettext.Tr("Upgrade Failed") + a.lastoreObj.sendNotify("preferences-system", "", msg, a.lastoreObj.createUpgradeFailedActions(), nil, notifyExpireTimeoutDefault, "dde-control-center") + // TODO 电量低的通知 + // TODO 下载完成通知用户去更新 + } + + return nil +} diff --git a/lastore/daemon.go b/lastore/daemon.go index 6b5220a95..09d680b5a 100644 --- a/lastore/daemon.go +++ b/lastore/daemon.go @@ -5,8 +5,8 @@ package lastore import ( - "github.com/linuxdeepin/go-lib/log" "github.com/linuxdeepin/dde-daemon/loader" + "github.com/linuxdeepin/go-lib/log" ) const ( @@ -22,6 +22,7 @@ func init() { type Daemon struct { lastore *Lastore + agent *Agent *loader.ModuleBase } @@ -38,13 +39,12 @@ func (*Daemon) GetDependencies() []string { func (d *Daemon) Start() error { service := loader.GetService() - lastore, err := newLastore(service) + lastoreObj, err := newLastore(service) if err != nil { return err } - d.lastore = lastore - - err = service.Export(dbusPath, lastore, lastore.syncConfig) + d.lastore = lastoreObj + err = service.Export(dbusPath, lastoreObj, lastoreObj.syncConfig) if err != nil { return err } @@ -53,32 +53,44 @@ func (d *Daemon) Start() error { if err != nil { return err } - - err = lastore.syncConfig.Register() + err = lastoreObj.syncConfig.Register() if err != nil { logger.Warning("Failed to register sync service:", err) } + agent, err := newAgent(lastoreObj) + if err != nil { + logger.Warning(err) + return err + } + d.agent = agent + agent.init() return nil } func (d *Daemon) Stop() error { - if d.lastore == nil { - return nil + if d.lastore != nil { + service := loader.GetService() + err := service.ReleaseName(dbusServiceName) + if err != nil { + logger.Warning(err) + } + d.lastore.destroy() + err = service.StopExport(d.lastore) + if err != nil { + logger.Warning(err) + } + + d.lastore = nil } - service := loader.GetService() - err := service.ReleaseName(dbusServiceName) - if err != nil { - logger.Warning(err) - } - - d.lastore.destroy() - - err = service.StopExport(d.lastore) - if err != nil { - logger.Warning(err) + if d.agent != nil { + service := loader.GetService() + d.agent.destroy() + err := service.StopExport(d.agent) + if err != nil { + logger.Warning(err) + } + d.agent = nil } - - d.lastore = nil return nil } diff --git a/lastore/exported_methods_auto.go b/lastore/exported_methods_auto.go index d3337afd4..146259fa1 100644 --- a/lastore/exported_methods_auto.go +++ b/lastore/exported_methods_auto.go @@ -1,4 +1,4 @@ -// Code generated by "dbusutil-gen em -type Lastore"; DO NOT EDIT. +// Code generated by "dbusutil-gen em -type Lastore,Agent"; DO NOT EDIT. package lastore @@ -6,6 +6,20 @@ import ( "github.com/linuxdeepin/go-lib/dbusutil" ) +func (v *Agent) GetExportedMethods() dbusutil.ExportedMethods { + return dbusutil.ExportedMethods{ + { + Name: "GetManualProxy", + Fn: v.GetManualProxy, + OutArgs: []string{"outArg0"}, + }, + { + Name: "SendNotify", + Fn: v.SendNotify, + InArgs: []string{"typ", "jobPath", "args"}, + }, + } +} func (v *Lastore) GetExportedMethods() dbusutil.ExportedMethods { return dbusutil.ExportedMethods{ { diff --git a/lastore/lastore.go b/lastore/lastore.go index c981ee463..637d561dd 100644 --- a/lastore/lastore.go +++ b/lastore/lastore.go @@ -6,25 +6,18 @@ package lastore import ( "os/exec" - "strings" "sync" "time" "github.com/godbus/dbus" - abrecovery "github.com/linuxdeepin/go-dbus-factory/com.deepin.abrecovery" + "github.com/linuxdeepin/dde-daemon/common/dsync" + network "github.com/linuxdeepin/go-dbus-factory/com.deepin.daemon.network" lastore "github.com/linuxdeepin/go-dbus-factory/com.deepin.lastore" - sessionmanager "github.com/linuxdeepin/go-dbus-factory/com.deepin.sessionmanager" - power "github.com/linuxdeepin/go-dbus-factory/com.deepin.system.power" - ofdbus "github.com/linuxdeepin/go-dbus-factory/org.freedesktop.dbus" notifications "github.com/linuxdeepin/go-dbus-factory/org.freedesktop.notifications" gio "github.com/linuxdeepin/go-gir/gio-2.0" "github.com/linuxdeepin/go-lib/dbusutil" "github.com/linuxdeepin/go-lib/dbusutil/proxy" "github.com/linuxdeepin/go-lib/gettext" - "github.com/linuxdeepin/go-lib/gsettings" - "github.com/linuxdeepin/go-lib/strv" - "github.com/linuxdeepin/dde-api/powersupply/battery" - "github.com/linuxdeepin/dde-daemon/common/dsync" ) //go:generate dbusutil-gen em -type Lastore @@ -33,67 +26,35 @@ type Lastore struct { service *dbusutil.Service sysSigLoop *dbusutil.SignalLoop sessionSigLoop *dbusutil.SignalLoop - jobStatus map[dbus.ObjectPath]CacheJobInfo - lang string - inhibitFd dbus.UnixFD - power power.Power - core lastore.Lastore - sysDBusDaemon ofdbus.DBus - notifications notifications.Notifications - sessionManager sessionmanager.SessionManager + core lastore.Lastore + notifications notifications.Notifications - syncConfig *dsync.Config - settings *gio.Settings - rebootTimer *time.Timer - updatingLowPowerPercent float64 - updateNotifyId uint32 - isBackuping bool - isUpdating bool + syncConfig *dsync.Config + settings *gio.Settings + rebootTimer *time.Timer // 默认间隔时间2小时,但当设置了稍后提醒时间后,需要修改默认时间,单位分钟 - intervalTime uint16 - needShowUpgradeFinishedNotify bool - - notifiedBattery bool - notifyIdHidMap map[uint32]dbusutil.SignalHandlerId - lastoreRule dbusutil.MatchRule - jobsPropsChangedHId dbusutil.SignalHandlerId - + intervalTime uint16 //TODO 需要修改成下载更新完成后提示用户去更新的时间 + notifyIdHidMap map[uint32]dbusutil.SignalHandlerId + network network.Network // prop: PropsMu sync.RWMutex SourceCheckEnabled bool } -type CacheJobInfo struct { - Id string - Status Status - Name string - Progress float64 - Type string -} - const ( - gsSchemaPower = "com.deepin.dde.power" - gsKeyUpdatingLowPowerPercent = "low-power-percent-in-updating-notify" - intervalTime10Min = 10 - intervalTime30Min = 30 - intervalTime120Min = 120 - intervalTime360Min = 360 + intervalTime10Min = 10 + intervalTime30Min = 30 + intervalTime120Min = 120 + intervalTime360Min = 360 ) func newLastore(service *dbusutil.Service) (*Lastore, error) { l := &Lastore{ - service: service, - jobStatus: make(map[dbus.ObjectPath]CacheJobInfo), - inhibitFd: -1, - lang: QueryLang(), - updateNotifyId: 0, - isUpdating: false, - intervalTime: intervalTime120Min, - needShowUpgradeFinishedNotify: false, + service: service, + intervalTime: intervalTime120Min, } - - logger.Debugf("CurrentLang: %q", l.lang) + l.network = network.NewNetwork(service.Conn()) systemBus, err := dbus.SystemBus() if err != nil { return nil, err @@ -109,84 +70,14 @@ func newLastore(service *dbusutil.Service) (*Lastore, error) { l.sessionSigLoop = dbusutil.NewSignalLoop(sessionBus, 10) l.sessionSigLoop.Start() - l.sessionManager = sessionmanager.NewSessionManager(sessionBus) - - l.settings = gio.NewSettings(gsSchemaPower) - l.updatingLowPowerPercent = l.settings.GetDouble(gsKeyUpdatingLowPowerPercent) - l.notifyGSettingsChanged() l.initCore(systemBus) l.initNotify(sessionBus) - l.initSysDBusDaemon(systemBus) - l.initPower(systemBus) - l.initABRecovery(systemBus) - l.listenBattery() l.syncConfig = dsync.NewConfig("updater", &syncConfig{l: l}, l.sessionSigLoop, dbusPath, logger) return l, nil } -func (l *Lastore) initPower(systemBus *dbus.Conn) { - l.power = power.NewPower(systemBus) - l.power.InitSignalExt(l.sysSigLoop, true) - err := l.power.HasBattery().ConnectChanged(func(hasValue bool, hasBattery bool) { - if !hasBattery { - l.notifiedBattery = false - } - }) - if err != nil { - logger.Warning(err) - } - - err = l.power.OnBattery().ConnectChanged(func(hasValue bool, onBattery bool) { - // 充电状态时,清除低电量横幅提示 - if hasValue && !onBattery { - l.removeLowBatteryInUpdatingNotify() - } - }) - if err != nil { - logger.Warning(err) - } -} - -func (l *Lastore) initABRecovery(systemBus *dbus.Conn) { - abRecovery := abrecovery.NewABRecovery(systemBus) - abRecovery.InitSignalExt(l.sysSigLoop, true) - - err := abRecovery.BackingUp().ConnectChanged(func(hasValue bool, hasBackup bool) { - if hasValue { - if hasBackup { - l.isBackuping = true - if l.needLowBatteryNotify() { - l.lowBatteryInUpdatingNotify() - } - } else { - l.isBackuping = false - } - } - }) - if err != nil { - logger.Warning(err) - } -} - -func (l *Lastore) listenBattery() { - err := l.power.BatteryPercentage().ConnectChanged(func(hasValue bool, value float64) { - if hasValue { - if value > l.updatingLowPowerPercent { - return - } - - if l.needLowBatteryNotify() { - l.lowBatteryInUpdatingNotify() - } - } - }) - if err != nil { - logger.Warning(err) - } -} - func (l *Lastore) initNotify(sessionBus *dbus.Conn) { l.notifications = notifications.NewNotifications(sessionBus) l.notifications.InitSignalExt(l.sessionSigLoop, true) @@ -210,162 +101,8 @@ func (l *Lastore) initNotify(sessionBus *dbus.Conn) { } } -func (l *Lastore) initSysDBusDaemon(systemBus *dbus.Conn) { - l.sysDBusDaemon = ofdbus.NewDBus(systemBus) - l.sysDBusDaemon.InitSignalExt(l.sysSigLoop, true) - _, err := l.sysDBusDaemon.ConnectNameOwnerChanged( - func(name string, oldOwner string, newOwner string) { - if name == l.core.ServiceName_() { - if newOwner == "" { - l.offline() - } else { - l.online() - } - } - }) - if err != nil { - logger.Warning(err) - } -} - -var allowPathList = []string{ - "/com/deepin/lastore/Jobprepare_system_upgrade", - "/com/deepin/lastore/Jobprepare_appstore_upgrade", - "/com/deepin/lastore/Jobprepare_security_upgrade", - "/com/deepin/lastore/Jobprepare_unknown_upgrade", - "/com/deepin/lastore/Jobsystem_upgrade", - "/com/deepin/lastore/Jobappstore_upgrade", - "/com/deepin/lastore/Jobsecurity_upgrade", - "/com/deepin/lastore/Jobunknown_upgrade", - "/com/deepin/lastore/Jobdist_upgrade", - "/com/deepin/lastore/Jobprepare_dist_upgrade", -} - -func (l *Lastore) isUpgradeJobType(path dbus.ObjectPath) bool { - job, ok := l.jobStatus[path] - if !ok { - return false - } - if !strv.Strv(allowPathList).Contains(string(path)) { - return false - } - if strings.Contains(string(path), "prepare") && strings.Contains(job.Name, "OnlyDownload") { - return false - } - return true -} - -func (l *Lastore) checkUpdateNotify(path dbus.ObjectPath) { - if !l.isUpgradeJobType(path) { - return - } - - l.isUpdating = true - // 当前job处于 end 状态时,不处理 - if l.jobStatus[path].Status == EndStatus { - l.isUpdating = false - return - } - - if l.needLowBatteryNotify() { - l.lowBatteryInUpdatingNotify() - } - if l.jobStatus[path].Id == SystemUpgradeJobType { - l.needShowUpgradeFinishedNotify = true - } - if !l.needShowUpgradeFinishedNotify { - return - } - - jobList, err := l.core.Manager().JobList().Get(0) - if err != nil { - logger.Warning(err) - } - - if l.jobStatus[path].Status == SucceedStatus { - for _, jobPath := range jobList { - if job, ok := l.jobStatus[jobPath]; ok { - if l.isUpgradeJobType(jobPath) { - if job.Status != SucceedStatus && job.Status != EndStatus && job.Status != FailedStatus { - return - } - if strings.Contains(string(jobPath), "prepare") { - return - } - } - } - } - - l.removeLowBatteryInUpdatingNotify() - l.updateSucceedNotify(l.createUpdateSucceedActions()) - l.isUpdating = false - l.needShowUpgradeFinishedNotify = false - } -} - -func (l *Lastore) needLowBatteryNotify() bool { - if l.updateNotifyId != 0 { - return false - } - - // 横幅未弹出,且处于ABRecovery或update状态时才弹出横幅 - if l.isUpdating || l.isBackuping { - batteryStatus, _ := l.power.BatteryStatus().Get(0) - hasBattery, _ := l.power.HasBattery().Get(0) - onBattery, _ := l.power.OnBattery().Get(0) - percent, _ := l.power.BatteryPercentage().Get(0) - if hasBattery && onBattery && percent < l.updatingLowPowerPercent && - batteryStatus != uint32(battery.StatusCharging) { - return true - } - } - - return false -} - func (l *Lastore) initCore(systemBus *dbus.Conn) { l.core = lastore.NewLastore(systemBus) - l.lastoreRule = dbusutil.NewMatchRuleBuilder(). - Sender(l.core.ServiceName_()). - Type("signal"). - Interface("org.freedesktop.DBus.Properties"). - Member("PropertiesChanged"). - Build() - err := l.lastoreRule.AddTo(systemBus) - if err != nil { - logger.Warning(err) - } - - l.core.InitSignalExt(l.sysSigLoop, false) - err = l.core.Manager().JobList().ConnectChanged(func(hasValue bool, value []dbus.ObjectPath) { - if !hasValue { - return - } - l.updateJobList(value) - }) - if err != nil { - logger.Warning(err) - } - - l.jobsPropsChangedHId = l.sysSigLoop.AddHandler(&dbusutil.SignalRule{ - Name: "org.freedesktop.DBus.Properties.PropertiesChanged", - }, func(sig *dbus.Signal) { - if len(sig.Body) != 3 { - return - } - props, _ := sig.Body[1].(map[string]dbus.Variant) - ifc, _ := sig.Body[0].(string) - if ifc == "com.deepin.lastore.Job" { - l.updateCacheJobInfo(sig.Path, props) - } - }) - - jobList, err := l.core.Manager().JobList().Get(0) - if err != nil { - logger.Warning(err) - } - - l.updateJobList(jobList) } func (l *Lastore) destroy() { @@ -373,14 +110,6 @@ func (l *Lastore) destroy() { l.sysSigLoop.Stop() l.syncConfig.Destroy() - systemBus := l.sysSigLoop.Conn() - err := l.lastoreRule.RemoveFrom(systemBus) - if err != nil { - logger.Warning(err) - } - - l.sysSigLoop.RemoveHandler(l.jobsPropsChangedHId) - l.power.RemoveHandler(proxy.RemoveAllHandlers) l.core.RemoveHandler(proxy.RemoveAllHandlers) l.notifications.RemoveHandler(proxy.RemoveAllHandlers) } @@ -389,37 +118,6 @@ func (l *Lastore) GetInterfaceName() string { return "com.deepin.LastoreSessionHelper" } -// updateJobList clean invalid cached Job status -// The list is the newest JobList. -func (l *Lastore) updateJobList(list []dbus.ObjectPath) { - var invalids []dbus.ObjectPath - for jobPath := range l.jobStatus { - safe := false - for _, p := range list { - if p == jobPath { - safe = true - break - } - } - if !safe { - invalids = append(invalids, jobPath) - } - } - for _, jobPath := range invalids { - delete(l.jobStatus, jobPath) - } - logger.Debugf("UpdateJobList: %v - %v", list, invalids) -} - -func (l *Lastore) offline() { - logger.Info("Lastore.Daemon Offline") - l.jobStatus = make(map[dbus.ObjectPath]CacheJobInfo) -} - -func (l *Lastore) online() { - logger.Info("Lastore.Daemon Online") -} - func (l *Lastore) createJobFailedActions(jobId string) []NotifyAction { ac := []NotifyAction{ { @@ -461,6 +159,45 @@ func (l *Lastore) createUpdateActions() []NotifyAction { return ac } +func (l *Lastore) createCanUpgradeActions() []NotifyAction { + // TODO 跳转至dde-shutdown的界面 + ac := []NotifyAction{ + { + Id: "update", + Name: gettext.Tr("Update Now"), + Callback: func() { + go func() { + err := exec.Command("dde-control-center", "-m", "update").Run() + if err != nil { + logger.Warningf("createUpdateActions: %v", err) + } + }() + }, + }, + } + + return ac +} +func (l *Lastore) createUpgradeFailedActions() []NotifyAction { + // TODO 具体操作未知 + ac := []NotifyAction{ + { + Id: "update", + Name: gettext.Tr("Update Now"), + Callback: func() { + go func() { + err := exec.Command("dde-control-center", "-m", "update").Run() + if err != nil { + logger.Warningf("createUpdateActions: %v", err) + } + }() + }, + }, + } + + return ac +} + func (l *Lastore) resetUpdateSucceedNotifyTimer(intervalTimeMinute uint16) { l.intervalTime = intervalTimeMinute if l.rebootTimer == nil { @@ -518,48 +255,6 @@ func (l *Lastore) createUpdateSucceedActions() []NotifyAction { return ac } -func (l *Lastore) notifyJob(path dbus.ObjectPath) { - l.checkBattery() - - info := l.jobStatus[path] - status := info.Status - logger.Debugf("notifyJob: %q %q --> %v", path, status, info) - if info.Name == "uos-release-note" { - logger.Debug("do not notify when package name is uos-release-note") - return - } - switch guestJobTypeFromPath(path) { - case InstallJobType: - switch status { - case FailedStatus: - l.notifyInstall(info.Name, false, l.createJobFailedActions(info.Id)) - case SucceedStatus: - if info.Progress == 1 { - l.notifyInstall(info.Name, true, nil) - } - } - case RemoveJobType: - switch status { - case FailedStatus: - l.notifyRemove(info.Name, false, l.createJobFailedActions(info.Id)) - case SucceedStatus: - l.notifyRemove(info.Name, true, nil) - } - - case CleanJobType: - if status == SucceedStatus && - strings.Contains(info.Name, "+notify") { - l.notifyAutoClean() - } - case UpdateSourceJobType, CustomUpdateJobType: - val, _ := l.core.Updater().UpdatablePackages().Get(0) - if status == SucceedStatus && len(val) > 0 && - strings.Contains(info.Name, "+notify") { - l.notifyUpdateSource(l.createUpdateActions()) - } - } -} - func (*Lastore) IsDiskSpaceSufficient() (result bool, busErr *dbus.Error) { avail, err := queryVFSAvailable("/") if err != nil { @@ -567,123 +262,3 @@ func (*Lastore) IsDiskSpaceSufficient() (result bool, busErr *dbus.Error) { } return avail > 1024*1024*10 /* 10 MB */, nil } - -func (l *Lastore) updateCacheJobInfo(path dbus.ObjectPath, props map[string]dbus.Variant) { - info := l.jobStatus[path] - oldStatus := info.Status - - systemBus := l.sysSigLoop.Conn() - job, err := lastore.NewJob(systemBus, path) - if err != nil { - logger.Warning(err) - return - } - - if info.Id == "" { - if v, ok := props["Id"]; ok { - info.Id, _ = v.Value().(string) - } - if info.Id == "" { - id, _ := job.Id().Get(dbus.FlagNoAutoStart) - info.Id = id - } - } - - if info.Name == "" { - if v, ok := props["Name"]; ok { - info.Name, _ = v.Value().(string) - } - if info.Name == "" { - name, _ := job.Name().Get(dbus.FlagNoAutoStart) - - if name == "" { - pkgs, _ := job.Packages().Get(dbus.FlagNoAutoStart) - if len(pkgs) == 0 { - name = "unknown" - } else { - name = PackageName(pkgs[0], l.lang) - } - } - - info.Name = name - } - } - - if v, ok := props["Progress"]; ok { - info.Progress, _ = v.Value().(float64) - } - - if v, ok := props["Status"]; ok { - status := v.Value().(string) - info.Status = Status(status) - } - - if info.Type == "" { - if v, ok := props["Type"]; ok { - info.Type, _ = v.Value().(string) - } - if info.Type == "" { - info.Type, _ = job.Type().Get(dbus.FlagNoAutoStart) - } - } else { - if v, ok := props["Type"]; ok { - info.Type, _ = v.Value().(string) - } - } - l.jobStatus[path] = info - logger.Debugf("updateCacheJobInfo: %#v", info) - - if oldStatus != info.Status { - l.notifyJob(path) - l.checkUpdateNotify(path) - } -} - -// guestJobTypeFromPath guest the JobType from object path -// We can't get the JobType when the DBusObject destroyed. -func guestJobTypeFromPath(path dbus.ObjectPath) string { - _path := string(path) - for _, jobType := range []string{ - // job types: - InstallJobType, DownloadJobType, RemoveJobType, - UpdateSourceJobType, DistUpgradeJobType, CleanJobType, CustomUpdateJobType, - } { - if strings.Contains(_path, jobType) { - return jobType - } - } - return "" -} - -var MinBatteryPercent = 30.0 - -func (l *Lastore) checkBattery() { - if l.notifiedBattery { - return - } - hasBattery, _ := l.power.HasBattery().Get(0) - onBattery, _ := l.power.OnBattery().Get(0) - percent, _ := l.power.BatteryPercentage().Get(0) - if hasBattery && onBattery && percent <= MinBatteryPercent { - l.notifiedBattery = true - l.notifyLowPower() - } -} - -func (l *Lastore) notifyGSettingsChanged() { - if l.settings == nil { - l.updatingLowPowerPercent = 50 - logger.Warning("failed to get gsetting") - return - } - - gsettings.ConnectChanged(gsSchemaPower, "*", func(key string) { - switch key { - case gsKeyUpdatingLowPowerPercent: - l.updatingLowPowerPercent = l.settings.GetDouble(key) - return - default: - return - } - }) -} diff --git a/lastore/notify.go b/lastore/notify.go index aa30a839c..ee1614459 100644 --- a/lastore/notify.go +++ b/lastore/notify.go @@ -5,7 +5,6 @@ package lastore import ( - "fmt" "os" "github.com/godbus/dbus" @@ -86,18 +85,6 @@ func (l *Lastore) sendNotify(icon string, summary string, msg string, actions [] l.notifyIdHidMap[id] = hid } -// NotifyInstall send desktop notify for install job -func (l *Lastore) notifyInstall(pkgId string, succeed bool, ac []NotifyAction) { - var msg string - if succeed { - msg = fmt.Sprintf(gettext.Tr("%q installed successfully."), pkgId) - l.sendNotify("package_install_succeed", "", msg, ac, nil, notifyExpireTimeoutDefault, getAppStoreAppName()) - } else { - msg = fmt.Sprintf(gettext.Tr("%q failed to install."), pkgId) - l.sendNotify("package_install_failed", "", msg, ac, nil, notifyExpireTimeoutDefault, getAppStoreAppName()) - } -} - func (l *Lastore) notifyRemove(pkgId string, succeed bool, ac []NotifyAction) { var msg string if succeed { @@ -125,6 +112,7 @@ func (l *Lastore) notifyUpdateSource(actions []NotifyAction) { } func (l *Lastore) updateSucceedNotify(actions []NotifyAction) { + // TODO delete summary := gettext.Tr("Reboot after Updates") msg := gettext.Tr("Restart the computer to use the system and applications properly") hints := map[string]dbus.Variant{"x-deepin-action-RebootNow": dbus.MakeVariant("busctl,--user,call,com.deepin.SessionManager," + @@ -134,32 +122,3 @@ func (l *Lastore) updateSucceedNotify(actions []NotifyAction) { // 默认弹出横幅时间为每2小时 l.resetUpdateSucceedNotifyTimer(l.intervalTime) } - -func (l *Lastore) lowBatteryInUpdatingNotify() { - msg := gettext.Tr("Your system is being updated, but the capacity is lower than 50%, please plug in to avoid power outage") - actions := []string{"ok", gettext.Tr("OK")} - notifyID, err := l.notifications.Notify(0, - "dde-control-center", - 0, - systemUpdatedIcon, - "", - msg, - actions, - nil, - 0, - ) - - if err != nil { - logger.Warning("failed to send notify:", err) - return - } - l.updateNotifyId = notifyID -} - -func (l *Lastore) removeLowBatteryInUpdatingNotify() { - err := l.notifications.CloseNotification(0, l.updateNotifyId) - if err != nil { - logger.Warningf("close low battery in updating notification failed,err:%v", err) - } - l.updateNotifyId = 0 -} diff --git a/lastore/system.go b/lastore/system.go deleted file mode 100644 index 8d1f498fc..000000000 --- a/lastore/system.go +++ /dev/null @@ -1,51 +0,0 @@ -// SPDX-FileCopyrightText: 2022 UnionTech Software Technology Co., Ltd. -// -// SPDX-License-Identifier: GPL-3.0-or-later - -package lastore - -import ( - "encoding/json" - "os" -) - -const ( - DownloadJobType = "download" - InstallJobType = "install" - RemoveJobType = "remove" - UpdateJobType = "update" - DistUpgradeJobType = "dist_upgrade" - PrepareDistUpgradeJobType = "prepare_dist_upgrade" - UpdateSourceJobType = "update_source" - CustomUpdateJobType = "custom_update" - CleanJobType = "clean" - SystemUpgradeJobType = "system_upgrade" -) - -type Status string - -const ( - ReadyStatus Status = "ready" - RunningStatus Status = "running" - FailedStatus Status = "failed" - SucceedStatus Status = "succeed" - PausedStatus Status = "paused" - - EndStatus = "end" -) -const varLibDir = "/var/lib/lastore" - -func decodeJson(fpath string, d interface{}) error { - f, err := os.Open(fpath) - if err != nil { - return err - } - defer func() { - err := f.Close() - if err != nil { - logger.Warning(err) - } - }() - - return json.NewDecoder(f).Decode(&d) -} diff --git a/lastore/tools.go b/lastore/tools.go index dbc807f41..42847922b 100644 --- a/lastore/tools.go +++ b/lastore/tools.go @@ -11,84 +11,10 @@ package lastore import "C" import ( - "os" - "path" "sort" - "strings" "unsafe" ) -// QueryLang return user lang. -// the rule is document at man gettext(3) -func QueryLang() string { - return QueryLangs()[0] -} - -// QueryLangs return array of user lang, split by ":". -// the rule is document at man gettext(3) -func QueryLangs() []string { - LC_ALL := os.Getenv("LC_ALL") - LC_MESSAGE := os.Getenv("LC_MESSAGE") - LANGUAGE := os.Getenv("LANGUAGE") - LANG := os.Getenv("LANG") - - cutoff := func(s string) string { - for i, c := range s { - if c == '.' { - return s[:i] - } - } - return s - } - - if LC_ALL != "C" && LANGUAGE != "" { - var r []string - for _, lang := range strings.Split(LANGUAGE, ":") { - r = append(r, cutoff(lang)) - } - return r - } - - if LC_ALL != "" { - return []string{cutoff(LC_ALL)} - } - if LC_MESSAGE != "" { - return []string{cutoff(LC_MESSAGE)} - } - if LANG != "" { - return []string{cutoff(LANG)} - } - return []string{""} -} - -func PackageName(pkg string, lang string) string { - names := make(map[string]struct { - Id string `json:"id"` - Name string `json:"name"` - LocaleName map[string]string `json:"locale_name"` - }) - - err := decodeJson(path.Join(varLibDir, "applications.json"), &names) - if err != nil { - logger.Warning(err) - } - - info, ok := names[pkg] - if !ok { - return pkg - } - - name := info.LocaleName[lang] - if name == "" { - if info.Name != "" { - name = info.Name - } else { - name = pkg - } - } - return name -} - func strSliceSetEqual(a, b []string) bool { if len(a) != len(b) { return false