screenShield: Show detailed notification data if notifications hint it

Allow notifications to set a x-gnome-privacy-scope hint, with values in
['system', 'user']. If all the notifications in a particular source hint
that their privacy scope is ‘system’, don’t hide the notification
details on the lock screen.

This is aimed at fixing the particular case of power notifications: they
contain information which is not private to the user (it relates to the
system: battery state or AC state, which is obvious to anyone who can
see the machine), so hiding the details of a power management
notification when the screen is locked is pointless.

Signed-off-by: Philip Withnall <withnall@endlessm.com>

https://gitlab.gnome.org/GNOME/gnome-shell/issues/726
This commit is contained in:
Philip Withnall 2018-11-01 20:56:25 +00:00 committed by Florian Müllner
parent 37e0a73c8f
commit e92477a752
3 changed files with 42 additions and 4 deletions

View File

@ -71,6 +71,17 @@ var Urgency = {
CRITICAL: 3 CRITICAL: 3
}; };
// The privacy of the details of a notification. USER is for notifications which
// contain private information to the originating user account (for example,
// details of an e-mail theyve received). SYSTEM is for notifications which
// contain information private to the physical system (for example, battery
// status) and hence the same for every user. This affects whether the content
// of a notification is shown on the lock screen.
var PrivacyScope = {
USER: 0,
SYSTEM: 1,
};
var FocusGrabber = class FocusGrabber { var FocusGrabber = class FocusGrabber {
constructor(actor) { constructor(actor) {
this._actor = actor; this._actor = actor;
@ -340,6 +351,7 @@ var Notification = class Notification {
this.resident = false; this.resident = false;
// 'transient' is a reserved keyword in JS, so we have to use an alternate variable name // 'transient' is a reserved keyword in JS, so we have to use an alternate variable name
this.isTransient = false; this.isTransient = false;
this.privacyScope = PrivacyScope.USER;
this.forFeedback = false; this.forFeedback = false;
this._acknowledged = false; this._acknowledged = false;
this.bannerBodyText = null; this.bannerBodyText = null;
@ -436,6 +448,10 @@ var Notification = class Notification {
this.forFeedback = forFeedback; this.forFeedback = forFeedback;
} }
setPrivacyScope(privacyScope) {
this.privacyScope = privacyScope;
}
playSound() { playSound() {
if (this._soundPlayed) if (this._soundPlayed)
return; return;
@ -722,6 +738,11 @@ var Source = class Source {
return new NotificationPolicy(); return new NotificationPolicy();
} }
get narrowestPrivacyScope() {
return this.notifications.every(n => n.privacyScope == PrivacyScope.SYSTEM) ? PrivacyScope.SYSTEM
: PrivacyScope.USER;
}
setTitle(newTitle) { setTitle(newTitle) {
this.title = newTitle; this.title = newTitle;
this.emit('title-changed'); this.emit('title-changed');

View File

@ -352,6 +352,10 @@ var FdoNotificationDaemon = class FdoNotificationDaemon {
// of the 'transient' hint with hints['transient'] rather than hints.transient // of the 'transient' hint with hints['transient'] rather than hints.transient
notification.setTransient(!!hints['transient']); notification.setTransient(!!hints['transient']);
let privacyScope = (hints['x-gnome-privacy-scope'] || 'user');
notification.setPrivacyScope(privacyScope == 'system' ? MessageTray.PrivacyScope.SYSTEM
: MessageTray.PrivacyScope.USER);
let sourceGIcon = source.useNotificationIcon ? gicon : null; let sourceGIcon = source.useNotificationIcon ? gicon : null;
source.processNotification(notification, sourceGIcon); source.processNotification(notification, sourceGIcon);
} }

View File

@ -203,6 +203,11 @@ var NotificationsBox = class {
return [title, null]; return [title, null];
} }
_shouldShowDetails(source) {
return source.policy.detailsInLockScreen ||
source.narrowestPrivacyScope == MessageTray.PrivacyScope.SYSTEM;
}
_showSource(source, obj, box) { _showSource(source, obj, box) {
if (obj.detailed) { if (obj.detailed) {
[obj.titleLabel, obj.countLabel] = this._makeNotificationDetailedSource(source, box); [obj.titleLabel, obj.countLabel] = this._makeNotificationDetailedSource(source, box);
@ -216,7 +221,7 @@ var NotificationsBox = class {
_sourceAdded(tray, source, initial) { _sourceAdded(tray, source, initial) {
let obj = { let obj = {
visible: source.policy.showInLockScreen, visible: source.policy.showInLockScreen,
detailed: source.policy.detailsInLockScreen, detailed: this._shouldShowDetails(source),
sourceDestroyId: 0, sourceDestroyId: 0,
sourceCountChangedId: 0, sourceCountChangedId: 0,
sourceTitleChangedId: 0, sourceTitleChangedId: 0,
@ -280,7 +285,14 @@ var NotificationsBox = class {
} }
_countChanged(source, obj) { _countChanged(source, obj) {
if (obj.detailed) { // A change in the number of notifications may change whether we show
// details.
let newDetailed = this._shouldShowDetails(source);
let oldDetailed = obj.detailed;
obj.detailed = newDetailed;
if (obj.detailed || oldDetailed != newDetailed) {
// A new notification was pushed, or a previous notification was destroyed. // A new notification was pushed, or a previous notification was destroyed.
// Give up, and build the list again. // Give up, and build the list again.
@ -312,10 +324,11 @@ var NotificationsBox = class {
} }
_detailedChanged(source, obj) { _detailedChanged(source, obj) {
if (obj.detailed == source.policy.detailsInLockScreen) let newDetailed = this._shouldShowDetails(source);
if (obj.detailed == newDetailed)
return; return;
obj.detailed = source.policy.detailsInLockScreen; obj.detailed = newDetailed;
obj.sourceBox.destroy_all_children(); obj.sourceBox.destroy_all_children();
obj.titleLabel = obj.countLabel = null; obj.titleLabel = obj.countLabel = null;