[gnome-shell] screenShield: Show detailed notification data if notifications hint it



commit e92477a7520dc45d8177472f0212dc27e70ab751
Author: Philip Withnall <withnall endlessm com>
Date:   Thu Nov 1 20:56:25 2018 +0000

    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

 js/ui/messageTray.js        | 21 +++++++++++++++++++++
 js/ui/notificationDaemon.js |  4 ++++
 js/ui/screenShield.js       | 21 +++++++++++++++++----
 3 files changed, 42 insertions(+), 4 deletions(-)
---
diff --git a/js/ui/messageTray.js b/js/ui/messageTray.js
index 97452275f..822cdeca4 100644
--- a/js/ui/messageTray.js
+++ b/js/ui/messageTray.js
@@ -71,6 +71,17 @@ var Urgency = {
     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 they’ve 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 {
     constructor(actor) {
         this._actor = actor;
@@ -340,6 +351,7 @@ var Notification = class Notification {
         this.resident = false;
         // 'transient' is a reserved keyword in JS, so we have to use an alternate variable name
         this.isTransient = false;
+        this.privacyScope = PrivacyScope.USER;
         this.forFeedback = false;
         this._acknowledged = false;
         this.bannerBodyText = null;
@@ -436,6 +448,10 @@ var Notification = class Notification {
         this.forFeedback = forFeedback;
     }
 
+    setPrivacyScope(privacyScope) {
+        this.privacyScope = privacyScope;
+    }
+
     playSound() {
         if (this._soundPlayed)
             return;
@@ -722,6 +738,11 @@ var Source = class Source {
         return new NotificationPolicy();
     }
 
+    get narrowestPrivacyScope() {
+        return this.notifications.every(n => n.privacyScope == PrivacyScope.SYSTEM) ? PrivacyScope.SYSTEM
+                                                                                    : PrivacyScope.USER;
+    }
+
     setTitle(newTitle) {
         this.title = newTitle;
         this.emit('title-changed');
diff --git a/js/ui/notificationDaemon.js b/js/ui/notificationDaemon.js
index 0a456f039..cd871a558 100644
--- a/js/ui/notificationDaemon.js
+++ b/js/ui/notificationDaemon.js
@@ -352,6 +352,10 @@ var FdoNotificationDaemon = class FdoNotificationDaemon {
         // of the 'transient' hint with hints['transient'] rather than 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;
         source.processNotification(notification, sourceGIcon);
     }
diff --git a/js/ui/screenShield.js b/js/ui/screenShield.js
index 5e9eae2e2..2f18390f3 100644
--- a/js/ui/screenShield.js
+++ b/js/ui/screenShield.js
@@ -203,6 +203,11 @@ var NotificationsBox = class {
         return [title, null];
     }
 
+    _shouldShowDetails(source) {
+        return source.policy.detailsInLockScreen ||
+               source.narrowestPrivacyScope == MessageTray.PrivacyScope.SYSTEM;
+    }
+
     _showSource(source, obj, box) {
         if (obj.detailed) {
             [obj.titleLabel, obj.countLabel] = this._makeNotificationDetailedSource(source, box);
@@ -216,7 +221,7 @@ var NotificationsBox = class {
     _sourceAdded(tray, source, initial) {
         let obj = {
             visible: source.policy.showInLockScreen,
-            detailed: source.policy.detailsInLockScreen,
+            detailed: this._shouldShowDetails(source),
             sourceDestroyId: 0,
             sourceCountChangedId: 0,
             sourceTitleChangedId: 0,
@@ -280,7 +285,14 @@ var NotificationsBox = class {
     }
 
     _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.
             // Give up, and build the list again.
 
@@ -312,10 +324,11 @@ var NotificationsBox = class {
     }
 
     _detailedChanged(source, obj) {
-        if (obj.detailed == source.policy.detailsInLockScreen)
+        let newDetailed = this._shouldShowDetails(source);
+        if (obj.detailed == newDetailed)
             return;
 
-        obj.detailed = source.policy.detailsInLockScreen;
+        obj.detailed = newDetailed;
 
         obj.sourceBox.destroy_all_children();
         obj.titleLabel = obj.countLabel = null;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]