diff --git a/desktop/notification/fdo.go b/desktop/notification/fdo.go index f5fdf6df128..99f2e8b9803 100644 --- a/desktop/notification/fdo.go +++ b/desktop/notification/fdo.go @@ -79,7 +79,8 @@ func (srv *Server) ServerCapabilities() ([]ServerCapability, error) { func (srv *Server) SendNotification(msg *Message) (ID, error) { call := srv.obj.Call(dBusInterfaceName+".Notify", 0, msg.AppName, msg.ReplacesID, msg.Icon, msg.Summary, msg.Body, - flattenActions(msg.Actions), mapHints(msg.Hints), msg.ExpireTimeout) + flattenActions(msg.Actions), mapHints(msg.Hints), + int32(msg.ExpireTimeout.Milliseconds())) var id ID if err := call.Store(&id); err != nil { return 0, err diff --git a/desktop/notification/fdo_test.go b/desktop/notification/fdo_test.go index a88d4124ba4..8be708224fd 100644 --- a/desktop/notification/fdo_test.go +++ b/desktop/notification/fdo_test.go @@ -23,6 +23,7 @@ import ( "context" "fmt" "sync" + "time" "github.com/godbus/dbus" . "gopkg.in/check.v1" @@ -231,7 +232,7 @@ func (s *fdoSuite) TestSendNotificationSuccess(c *C) { Icon: "icon", Summary: "summary", Body: "body", - ExpireTimeout: 1000, + ExpireTimeout: time.Second * 1, ReplacesID: notification.ID(42), Actions: []notification.Action{ {ActionKey: "key-1", LocalizedText: "text-1"}, @@ -246,6 +247,34 @@ func (s *fdoSuite) TestSendNotificationSuccess(c *C) { c.Check(id, Equals, notification.ID(7)) } +func (s *fdoSuite) TestSendNotificationWithServerDecitedExpireTimeout(c *C) { + srv := s.connectWithHandler(c, func(msg *dbus.Message, n int) ([]*dbus.Message, error) { + switch n { + case 0: + s.checkNotifyRequest(c, msg) + c.Check(msg.Body[7], Equals, int32(-1)) + responseSig := dbus.SignatureOf(uint32(0)) + response := &dbus.Message{ + Type: dbus.TypeMethodReply, + Headers: map[dbus.HeaderField]dbus.Variant{ + dbus.FieldReplySerial: dbus.MakeVariant(msg.Serial()), + dbus.FieldSender: dbus.MakeVariant(":1"), // This does not matter. + // dbus.FieldDestination is provided automatically by DBus test helper. + dbus.FieldSignature: dbus.MakeVariant(responseSig), + }, + Body: []interface{}{uint32(7)}, + } + return []*dbus.Message{response}, nil + } + return nil, fmt.Errorf("unexpected message #%d: %s", n, msg) + }) + id, err := srv.SendNotification(¬ification.Message{ + ExpireTimeout: notification.ServerSelectedExpireTimeout, + }) + c.Assert(err, IsNil) + c.Check(id, Equals, notification.ID(7)) +} + func (s *fdoSuite) TestSendNotificationError(c *C) { srv := s.connectWithHandler(c, func(msg *dbus.Message, n int) ([]*dbus.Message, error) { switch n { diff --git a/desktop/notification/notify.go b/desktop/notification/notify.go index d89cb5a3320..8043d6df66a 100644 --- a/desktop/notification/notify.go +++ b/desktop/notification/notify.go @@ -23,6 +23,7 @@ package notification import ( "fmt" + "time" ) // Message describes a single notification message. @@ -38,7 +39,10 @@ import ( // A notification can automatically expire after the given number of // milliseconds. This is separate from the notification being visible or // invisible on-screen. Expired notifications are removed from persistent -// message roster, if one is supported. +// message roster, if one is supported. Two special values are recognized. When +// the expiration timeout is zero a message never expires. When the expiration +// timeout is -1 a message expires after a server-defined duration which may +// vary for the type of the notification message sent. // // A notification may replace an existing notification by setting the ReplacesID // to a non-zero value. This only works if the notification server was not @@ -63,12 +67,16 @@ type Message struct { Icon string Summary string Body string - ExpireTimeout int32 // XXX: consider using time.Duration instead? + ExpireTimeout time.Duration // Effective resolution in milliseconds with 31-bit range. ReplacesID ID Actions []Action Hints []Hint } +// ServerSelectedExpireTimeout requests the server to pick an expiration timeout +// appropriate for the message type. +const ServerSelectedExpireTimeout = time.Millisecond * -1 + // ID is the opaque identifier of a notification assigned by the server. // // Notifications with known identifiers can be closed or updated. The identifier