[gnome-shell/wip/gdbus: 3/4] notificationDaemon, magnifierDBus: port to GDBus



commit fb7f03050016ba0705d3f9983372fe4795122162
Author: Giovanni Campagna <gcampagna src gnome org>
Date:   Tue Aug 16 14:26:49 2011 +0200

    notificationDaemon, magnifierDBus: port to GDBus
    
    Move /org/freedesktop/Notifications and /org/gnome/Magnifier to the
    GDBus connection, so they're matched with the appropriate DBus name.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=648651

 js/ui/magnifierDBus.js      |  135 +++++++++++++++++++----------
 js/ui/notificationDaemon.js |  201 ++++++++++++++++++++++--------------------
 2 files changed, 194 insertions(+), 142 deletions(-)
---
diff --git a/js/ui/magnifierDBus.js b/js/ui/magnifierDBus.js
index aefeb49..4c268fb 100644
--- a/js/ui/magnifierDBus.js
+++ b/js/ui/magnifierDBus.js
@@ -1,6 +1,7 @@
 // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
 
-const DBus = imports.dbus;
+const Gio = imports.gi.Gio;
+const GLib = imports.gi.GLib;
 const Main = imports.ui.main;
 
 const MAG_SERVICE_NAME = 'org.gnome.Magnifier';
@@ -10,47 +11,85 @@ const ZOOM_SERVICE_PATH = '/org/gnome/Magnifier/ZoomRegion';
 
 // Subset of gnome-mag's Magnifier dbus interface -- to be expanded.  See:
 // http://git.gnome.org/browse/gnome-mag/tree/xml/...Magnifier.xml
-const MagnifierIface = {
-    name: MAG_SERVICE_NAME,
-    methods: [
-                { name: 'setActive', inSignature: 'b', outSignature: '' },
-                { name: 'isActive', inSignature: '', outSignature: 'b' },
-                { name: 'showCursor', inSignature: '', outSignature: '' },
-                { name: 'hideCursor', inSignature: '', outSignature: ''  },
-                { name: 'createZoomRegion', inSignature: 'ddaiai', outSignature: 'o' },
-                { name: 'addZoomRegion', inSignature: 'o', outSignature: 'b' },
-                { name: 'getZoomRegions', inSignature: '', outSignature: 'ao' },
-                { name: 'clearAllZoomRegions', inSignature: '', outSignature: '' },
-                { name: 'fullScreenCapable', inSignature: '', outSignature: 'b' },
-
-                { name: 'setCrosswireSize', inSignature: 'i', outSignature: '' },
-                { name: 'getCrosswireSize', inSignature: '', outSignature: 'i' },
-                { name: 'setCrosswireLength', inSignature: 'i', outSignature: '' },
-                { name: 'getCrosswireLength', inSignature: '', outSignature: 'i' },
-                { name: 'setCrosswireClip', inSignature: 'b', outSignature: '' },
-                { name: 'getCrosswireClip', inSignature: '', outSignature: 'b' },
-                { name: 'setCrosswireColor', inSignature: 'u', outSignature: '' },
-                { name: 'getCrosswireColor', inSignature: '', outSignature: 'u' }
-             ],
-    signals: [],
-    properties: []
-};
+const MagnifierIface = <interface name={MAG_SERVICE_NAME}>
+<method name="setActive">
+    <arg type="b" direction="in" />
+</method>
+<method name="isActive">
+    <arg type="b" direction="out" />
+</method>
+<method name="showCursor" />
+<method name="hideCursor" />
+<method name="createZoomRegion">
+    <arg type="d" direction="in" />
+    <arg type="d" direction="in" />
+    <arg type="ai" direction="in" />
+    <arg type="ai" direction="in" />
+    <arg type="o" direction="out" />
+</method>
+<method name="addZoomRegion">
+    <arg type="o" direction="in" />
+    <arg type="b" direction="out" />
+</method>
+<method name="getZoomRegions">
+    <arg type="ao" direction="out" />
+</method>
+<method name="clearAllZoomRegions" />
+<method name="fullScreenCapable">
+    <arg type="b" direction="out" />
+</method>
+<method name="setCrosswireSize">
+    <arg type="i" direction="in" />
+</method>
+<method name="getCrosswireSize">
+    <arg type="i" direction="out" />
+</method>
+<method name="setCrosswireLength">
+    <arg type="i" direction="in" />
+</method>
+<method name="getCrosswireLength">
+    <arg type="i" direction="out" />
+</method>
+<method name="setCrosswireClip">
+    <arg type="b" direction="in" />
+</method>
+<method name="getCrosswireClip">
+    <arg type="b" direction="out" />
+</method>
+<method name="setCrosswireColor">
+    <arg type="u" direction="in" />
+</method>
+<method name="getCrosswireColor">
+    <arg type="u" direction="out" />
+</method>
+</interface>;
 
 // Subset of gnome-mag's ZoomRegion dbus interface -- to be expanded.  See:
 // http://git.gnome.org/browse/gnome-mag/tree/xml/...ZoomRegion.xml
-const ZoomRegionIface = {
-    name: ZOOM_SERVICE_NAME,
-    methods: [
-                { name: 'setMagFactor', inSignature: 'dd', outSignature: ''},
-                { name: 'getMagFactor', inSignature: '', outSignature: 'dd' },
-                { name: 'setRoi', inSignature: 'ai', outSignature: '' },
-                { name: 'getRoi', inSignature: '', outSignature: 'ai' },
-                { name: 'shiftContentsTo', inSignature: 'ii', outSignature: 'b' },
-                { name: 'moveResize', inSignature: 'ai', outSignature: '' }
-             ],
-    signals: [],
-    properties: []
-};
+const ZoomRegionIface = <interface name={ZOOM_SERVICE_NAME}>
+<method name="setMagFactor">
+    <arg type="d" direction="in" />
+    <arg type="d" direction="in" />
+</method>
+<method name="getMagFactor">
+    <arg type="d" direction="out" />
+    <arg type="d" direction="out" />
+</method>
+<method name="setRoi">
+    <arg type="ai" direction="in" />
+</method>
+<method name="getRoi">
+    <arg type="ai" direction="out" />
+</method>
+<method name="shiftContentsTo">
+    <arg type="i" direction="in" />
+    <arg type="i" direction="in" />
+    <arg type="b" direction="out" />
+</method>
+<method name="moveResize">
+    <arg type="ai" direction="in" />
+</method>
+</interface>;
 
 // For making unique ZoomRegion DBus proxy object paths of the form:
 // '/org/gnome/Magnifier/ZoomRegion/zoomer0',
@@ -64,7 +103,9 @@ function ShellMagnifier() {
 ShellMagnifier.prototype = {
     _init: function() {
         this._zoomers = {};
-        DBus.session.exportObject(MAG_SERVICE_PATH, this);
+
+        this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(MagnifierIface, this);
+        this._dbusImpl.export(Gio.DBus.session, MAG_SERVICE_PATH);
     },
 
     /**
@@ -195,10 +236,10 @@ ShellMagnifier.prototype = {
         Main.magnifier.clearAllZoomRegions();
         for (let objectPath in this._zoomers) {
             let proxyAndZoomer = this._zoomers[objectPath];
+            proxyAndZoomer.proxy.destroy();
             proxyAndZoomer.proxy = null;
             proxyAndZoomer.zoomRegion = null;
             delete this._zoomers[objectPath];
-            DBus.session.unexportObject(proxyAndZoomer);
         }
         this._zoomers = {};
     },
@@ -300,8 +341,9 @@ function ShellMagnifierZoomRegion(zoomerObjectPath, zoomRegion) {
 ShellMagnifierZoomRegion.prototype = {
     _init: function(zoomerObjectPath, zoomRegion) {
         this._zoomRegion = zoomRegion;
-        DBus.session.proxifyObject(this, ZOOM_SERVICE_NAME, zoomerObjectPath);
-        DBus.session.exportObject(zoomerObjectPath, this);
+
+        this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(ZoomRegionIface, this);
+        this._dbusImpl.export(Gio.DBus.session, zoomerObjectPath);
     },
 
     /**
@@ -376,8 +418,9 @@ ShellMagnifierZoomRegion.prototype = {
     moveResize: function(viewPort) {
         let viewRect = { x: viewPort[0], y: viewPort[1], width: viewPort[2] - viewPort[0], height: viewPort[3] - viewPort[1] };
         this._zoomRegion.setViewPort(viewRect);
+    },
+
+    destroy: function() {
+        this._dbusImpl.unexport();
     }
 };
-
-DBus.conformExport(ShellMagnifier.prototype, MagnifierIface);
-DBus.conformExport(ShellMagnifierZoomRegion.prototype, ZoomRegionIface);
diff --git a/js/ui/notificationDaemon.js b/js/ui/notificationDaemon.js
index f40205d..98b8875 100644
--- a/js/ui/notificationDaemon.js
+++ b/js/ui/notificationDaemon.js
@@ -1,7 +1,7 @@
 // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
 
 const Clutter = imports.gi.Clutter;
-const DBus = imports.dbus;
+const Gio = imports.gi.Gio;
 const GLib = imports.gi.GLib;
 const Lang = imports.lang;
 const Shell = imports.gi.Shell;
@@ -16,49 +16,52 @@ const Util = imports.misc.util;
 
 let nextNotificationId = 1;
 
-// Should really be defined in dbus.js
-const BusIface = {
-    name: 'org.freedesktop.DBus',
-    methods: [{ name: 'GetConnectionUnixProcessID',
-                inSignature: 's',
-                outSignature: 'i' }]
-};
-
-const Bus = function () {
-    this._init();
-};
-
-Bus.prototype = {
-     _init: function() {
-         DBus.session.proxifyObject(this, 'org.freedesktop.DBus', '/org/freedesktop/DBus');
-     }
-};
+// Should really be defined in Gio.js
+const BusIface = <interface name="org.freedesktop.DBus">
+<method name="GetConnectionUnixProcessID">
+    <arg type="s" direction="in" />
+    <arg type="u" direction="out" />
+</method>
+</interface>;
+
+var BusProxy = Gio.DBusProxy.makeProxyWrapper(BusIface);
+function Bus() {
+    return new BusProxy(Gio.DBus.session, 'org.freedesktop.DBus', '/org/freedesktop/DBus');
+}
 
-DBus.proxifyPrototype(Bus.prototype, BusIface);
-
-const NotificationDaemonIface = {
-    name: 'org.freedesktop.Notifications',
-    methods: [{ name: 'Notify',
-                inSignature: 'susssasa{sv}i',
-                outSignature: 'u'
-              },
-              { name: 'CloseNotification',
-                inSignature: 'u',
-                outSignature: ''
-              },
-              { name: 'GetCapabilities',
-                inSignature: '',
-                outSignature: 'as'
-              },
-              { name: 'GetServerInformation',
-                inSignature: '',
-                outSignature: 'ssss'
-              }],
-    signals: [{ name: 'NotificationClosed',
-                inSignature: 'uu' },
-              { name: 'ActionInvoked',
-                inSignature: 'us' }]
-};
+const NotificationDaemonIface = <interface name="org.freedesktop.Notifications">
+<method name="Notify">
+    <arg type="s" direction="in"/>
+    <arg type="u" direction="in"/>
+    <arg type="s" direction="in"/>
+    <arg type="s" direction="in"/>
+    <arg type="s" direction="in"/>
+    <arg type="as" direction="in"/>
+    <arg type="a{sv}" direction="in"/>
+    <arg type="i" direction="in"/>
+    <arg type="u" direction="out"/>
+</method>
+<method name="CloseNotification">
+    <arg type="u" direction="in"/>
+</method>
+<method name="GetCapabilities">
+    <arg type="as" direction="out"/>
+</method>
+<method name="GetServerInformation">
+    <arg type="s" direction="out"/>
+    <arg type="s" direction="out"/>
+    <arg type="s" direction="out"/>
+    <arg type="s" direction="out"/>
+</method>
+<signal name="NotificationClosed">
+    <arg type="u"/>
+    <arg type="u"/>
+</signal>
+<signal name="ActionInvoked">
+    <arg type="u"/>
+    <arg type="s"/>
+</signal>
+</interface>;
 
 const NotificationClosedReason = {
     EXPIRED: 1,
@@ -90,7 +93,8 @@ function NotificationDaemon() {
 
 NotificationDaemon.prototype = {
     _init: function() {
-        DBus.session.exportObject('/org/freedesktop/Notifications', this);
+        this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(NotificationDaemonIface, this);
+        this._dbusImpl.export(Gio.DBus.session, '/org/freedesktop/Notifications');
 
         this._sources = {};
         this._senderToPid = {};
@@ -195,8 +199,8 @@ NotificationDaemon.prototype = {
         return source;
     },
 
-    Notify: function(appName, replacesId, icon, summary, body,
-                     actions, hints, timeout) {
+    NotifyAsync: function(params, invocation) {
+        let [appName, replacesId, icon, summary, body, actions, hints, timeout] = params;
         let id;
 
         // Filter out chat, presence, calls and invitation notifications from
@@ -215,7 +219,7 @@ NotificationDaemon.prototype = {
                                         function () {
                                             this._emitNotificationClosed(id, NotificationClosedReason.DISMISSED);
                                         }));
-            return id;
+            return invocation.return_value(GLib.Variant.new('(u)', [id]));
         }
 
         let rewrites = rewriteRules[appName];
@@ -227,6 +231,11 @@ NotificationDaemon.prototype = {
             }
         }
 
+        for (let hint in hints) {
+            // unpack the variants
+            hints[hint] = hints[hint].deep_unpack();
+        }
+
         hints = Params.parse(hints, { urgency: Urgency.NORMAL }, true);
 
         // Be compatible with the various hints for image data and image path
@@ -258,51 +267,55 @@ NotificationDaemon.prototype = {
         }
         this._notifications[id] = ndata;
 
-        let sender = DBus.getCurrentMessageContext().sender;
+        let sender = invocation.get_sender();
         let pid = this._senderToPid[sender];
 
         let source = this._getSource(appName, pid, ndata, sender);
 
         if (source) {
             this._notifyForSource(source, ndata);
-            return id;
+            return invocation.return_value(GLib.Variant.new('(u)', [id]));
         }
 
         if (replacesId) {
             // There's already a pending call to GetConnectionUnixProcessID,
             // which will see the new notification data when it finishes,
             // so we don't have to do anything.
-            return id;
+            return invocation.return_value(GLib.Variant.new('(u)', [id]));;
         }
 
-        this._busProxy.GetConnectionUnixProcessIDRemote(sender, Lang.bind(this,
-            function (pid, ex) {
-                // The app may have updated or removed the notification
-                ndata = this._notifications[id];
-                if (!ndata)
-                    return;
-
-                source = this._getSource(appName, pid, ndata, sender);
-
-                // We only store sender-pid entries for persistent sources.
-                // Removing the entries once the source is destroyed
-                // would result in the entries associated with transient
-                // sources removed once the notification is shown anyway.
-                // However, keeping these pairs would mean that we would
-                // possibly remove an entry associated with a persistent
-                // source when a transient source for the same sender is
-                // distroyed.
-                if (!source.isTransient) {
-                    this._senderToPid[sender] = pid;
-                    source.connect('destroy', Lang.bind(this,
-                        function() {
-                            delete this._senderToPid[sender];
-                        }));
-                }
-                this._notifyForSource(source, ndata);
-            }));
+        this._busProxy.GetConnectionUnixProcessIDRemote(sender, Lang.bind(this, function (result, excp) {
+            // The app may have updated or removed the notification
+            ndata = this._notifications[id];
+            if (!ndata)
+                return;
+
+            if (excp) {
+                logError(excp, 'Call to GetConnectionUnixProcessID failed');
+                return;
+            }
+
+            let [pid] = result;
+            source = this._getSource(appName, pid, ndata, sender);
+
+            // We only store sender-pid entries for persistent sources.
+            // Removing the entries once the source is destroyed
+            // would result in the entries associated with transient
+            // sources removed once the notification is shown anyway.
+            // However, keeping these pairs would mean that we would
+            // possibly remove an entry associated with a persistent
+            // source when a transient source for the same sender is
+            // distroyed.
+            if (!source.isTransient) {
+                this._senderToPid[sender] = pid;
+                source.connect('destroy', Lang.bind(this, function() {
+                    delete this._senderToPid[sender];
+                }));
+            }
+            this._notifyForSource(source, ndata);
+        }));
 
-        return id;
+        return invocation.return_value(GLib.Variant.new('(u)', [id]));
     },
 
     _notifyForSource: function(source, ndata) {
@@ -442,17 +455,13 @@ NotificationDaemon.prototype = {
     },
 
     _emitNotificationClosed: function(id, reason) {
-        DBus.session.emit_signal('/org/freedesktop/Notifications',
-                                 'org.freedesktop.Notifications',
-                                 'NotificationClosed', 'uu',
-                                 [id, reason]);
+        this._dbusImpl.emit_signal('NotificationClosed',
+                                   GLib.Variant.new('(uu)', [id, reason]));
     },
 
     _emitActionInvoked: function(id, action) {
-        DBus.session.emit_signal('/org/freedesktop/Notifications',
-                                 'org.freedesktop.Notifications',
-                                 'ActionInvoked', 'us',
-                                 [id, action]);
+        this._dbusImpl.emit_signal('ActionInvoked',
+                                   GLib.Variant.new('(us)', [id, action]));
     },
 
     _onTrayIconAdded: function(o, icon) {
@@ -467,8 +476,6 @@ NotificationDaemon.prototype = {
     }
 };
 
-DBus.conformExport(NotificationDaemon.prototype, NotificationDaemonIface);
-
 function Source(title, pid, sender) {
     this._init(title, pid, sender);
 }
@@ -481,15 +488,12 @@ Source.prototype = {
 
         this._pid = pid;
         if (sender)
-            // TODO: dbus-glib implementation of watch_name() doesnât return an id to be used for
-            // unwatch_name() or implement unwatch_name(), however when we move to using GDBus implementation,
-            // we should save the id here and call unwatch_name() with it in destroy().
-            // Moving to GDBus is the work in progress: https://bugzilla.gnome.org/show_bug.cgi?id=648651
-            // and https://bugzilla.gnome.org/show_bug.cgi?id=622921 .
-            DBus.session.watch_name(sender,
-                                    false,
-                                    null,
-                                    Lang.bind(this, this._onNameVanished));
+            this._nameWatcherId = Gio.DBus.session.watch_name(sender,
+                                                              Gio.BusNameWatcherFlags.NONE,
+                                                              null,
+                                                              Lang.bind(this, this._onNameVanished));
+        else
+            this._nameWatcherId = 0;
 
         this._setApp();
         if (this.app)
@@ -597,6 +601,11 @@ Source.prototype = {
     },
 
     destroy: function() {
+        if (this._nameWatcherId) {
+            Gio.DBus.session.unwatch_name(this._nameWatcherId);
+            this._nameWatcherId = 0;
+        }
+
         MessageTray.Source.prototype.destroy.call(this);
     }
 };



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