|
|
f3cbb9 |
From 1fc22df08e365820fedccf92b95601859ce63f5b Mon Sep 17 00:00:00 2001
|
|
|
f3cbb9 |
From: Ray Strode <rstrode@redhat.com>
|
|
|
f3cbb9 |
Date: Fri, 7 Oct 2016 15:40:14 -0400
|
|
|
f3cbb9 |
Subject: [PATCH 1/2] objectManager: handle proxies coming and going
|
|
|
f3cbb9 |
|
|
|
f3cbb9 |
Ever since commit b8e29ae8c78658917c8a8ddd391667d7d9e36971
|
|
|
f3cbb9 |
(I think), start up is littered with this message:
|
|
|
f3cbb9 |
|
|
|
f3cbb9 |
Gjs-WARNING **: JS ERROR: could not get remote objects for service
|
|
|
f3cbb9 |
org.gnome.SettingsDaemon.Smartcard path
|
|
|
f3cbb9 |
|
|
|
f3cbb9 |
since gnome-shell is now started before gnome-settings-daemon.
|
|
|
f3cbb9 |
|
|
|
f3cbb9 |
This commit addresses the problem by making the object manager code
|
|
|
f3cbb9 |
not try to autostart its proxy, and instead wait for it to appear.
|
|
|
f3cbb9 |
|
|
|
f3cbb9 |
https://bugzilla.gnome.org/show_bug.cgi?id=772589
|
|
|
f3cbb9 |
---
|
|
|
f3cbb9 |
js/misc/objectManager.js | 34 ++++++++++++++++++++++++++++++++--
|
|
|
f3cbb9 |
1 files changed, 34 insertions(+), 2 deletions(-)
|
|
|
f3cbb9 |
|
|
|
f3cbb9 |
diff --git a/js/misc/objectManager.js b/js/misc/objectManager.js
|
|
|
f3cbb9 |
index 225204347..5db7588b6 100644
|
|
|
f3cbb9 |
--- a/js/misc/objectManager.js
|
|
|
f3cbb9 |
+++ b/js/misc/objectManager.js
|
|
|
f3cbb9 |
@@ -19,101 +19,104 @@ const ObjectManagerIface = '<node> \
|
|
|
f3cbb9 |
</signal> \
|
|
|
f3cbb9 |
<signal name="InterfacesRemoved"> \
|
|
|
f3cbb9 |
<arg name="objectPath" type="o"/> \
|
|
|
f3cbb9 |
<arg name="interfaces" type="as" /> \
|
|
|
f3cbb9 |
</signal> \
|
|
|
f3cbb9 |
</interface> \
|
|
|
f3cbb9 |
</node>';
|
|
|
f3cbb9 |
|
|
|
f3cbb9 |
const ObjectManagerInfo = Gio.DBusInterfaceInfo.new_for_xml(ObjectManagerIface);
|
|
|
f3cbb9 |
|
|
|
f3cbb9 |
const ObjectManager = new Lang.Class({
|
|
|
f3cbb9 |
Name: 'ObjectManager',
|
|
|
f3cbb9 |
_init: function(params) {
|
|
|
f3cbb9 |
params = Params.parse(params, { connection: null,
|
|
|
f3cbb9 |
name: null,
|
|
|
f3cbb9 |
objectPath: null,
|
|
|
f3cbb9 |
knownInterfaces: null,
|
|
|
f3cbb9 |
cancellable: null,
|
|
|
f3cbb9 |
onLoaded: null });
|
|
|
f3cbb9 |
|
|
|
f3cbb9 |
this._connection = params.connection;
|
|
|
f3cbb9 |
this._serviceName = params.name;
|
|
|
f3cbb9 |
this._managerPath = params.objectPath;
|
|
|
f3cbb9 |
this._cancellable = params.cancellable;
|
|
|
f3cbb9 |
|
|
|
f3cbb9 |
this._managerProxy = new Gio.DBusProxy({ g_connection: this._connection,
|
|
|
f3cbb9 |
g_interface_name: ObjectManagerInfo.name,
|
|
|
f3cbb9 |
g_interface_info: ObjectManagerInfo,
|
|
|
f3cbb9 |
g_name: this._serviceName,
|
|
|
f3cbb9 |
g_object_path: this._managerPath,
|
|
|
f3cbb9 |
- g_flags: Gio.DBusProxyFlags.NONE });
|
|
|
f3cbb9 |
+ g_flags: Gio.DBusProxyFlags.DO_NOT_AUTO_START });
|
|
|
f3cbb9 |
|
|
|
f3cbb9 |
this._interfaceInfos = {};
|
|
|
f3cbb9 |
this._objects = {};
|
|
|
f3cbb9 |
this._interfaces = {};
|
|
|
f3cbb9 |
this._onLoaded = params.onLoaded;
|
|
|
f3cbb9 |
|
|
|
f3cbb9 |
if (params.knownInterfaces)
|
|
|
f3cbb9 |
this._registerInterfaces(params.knownInterfaces);
|
|
|
f3cbb9 |
|
|
|
f3cbb9 |
// Start out inhibiting load until at least the proxy
|
|
|
f3cbb9 |
// manager is loaded and the remote objects are fetched
|
|
|
f3cbb9 |
this._numLoadInhibitors = 1;
|
|
|
f3cbb9 |
this._managerProxy.init_async(GLib.PRIORITY_DEFAULT,
|
|
|
f3cbb9 |
this._cancellable,
|
|
|
f3cbb9 |
Lang.bind(this, this._onManagerProxyLoaded));
|
|
|
f3cbb9 |
},
|
|
|
f3cbb9 |
|
|
|
f3cbb9 |
_tryToCompleteLoad: function() {
|
|
|
f3cbb9 |
+ if (this._numLoadInhibitors == 0)
|
|
|
f3cbb9 |
+ return;
|
|
|
f3cbb9 |
+
|
|
|
f3cbb9 |
this._numLoadInhibitors--;
|
|
|
f3cbb9 |
if (this._numLoadInhibitors == 0) {
|
|
|
f3cbb9 |
if (this._onLoaded)
|
|
|
f3cbb9 |
this._onLoaded();
|
|
|
f3cbb9 |
}
|
|
|
f3cbb9 |
},
|
|
|
f3cbb9 |
|
|
|
f3cbb9 |
_addInterface: function(objectPath, interfaceName, onFinished) {
|
|
|
f3cbb9 |
let info = this._interfaceInfos[interfaceName];
|
|
|
f3cbb9 |
|
|
|
f3cbb9 |
if (!info) {
|
|
|
f3cbb9 |
if (onFinished)
|
|
|
f3cbb9 |
onFinished();
|
|
|
f3cbb9 |
return;
|
|
|
f3cbb9 |
}
|
|
|
f3cbb9 |
|
|
|
f3cbb9 |
let proxy = new Gio.DBusProxy({ g_connection: this._connection,
|
|
|
f3cbb9 |
g_name: this._serviceName,
|
|
|
f3cbb9 |
g_object_path: objectPath,
|
|
|
f3cbb9 |
g_interface_name: interfaceName,
|
|
|
f3cbb9 |
g_interface_info: info,
|
|
|
f3cbb9 |
- g_flags: Gio.DBusProxyFlags.NONE });
|
|
|
f3cbb9 |
+ g_flags: Gio.DBusProxyFlags.DO_NOT_AUTO_START });
|
|
|
f3cbb9 |
|
|
|
f3cbb9 |
proxy.init_async(GLib.PRIORITY_DEFAULT,
|
|
|
f3cbb9 |
this._cancellable,
|
|
|
f3cbb9 |
Lang.bind(this, function(initable, result) {
|
|
|
f3cbb9 |
let error = null;
|
|
|
f3cbb9 |
try {
|
|
|
f3cbb9 |
initable.init_finish(result);
|
|
|
f3cbb9 |
} catch(e) {
|
|
|
f3cbb9 |
logError(e, 'could not initialize proxy for interface ' + interfaceName);
|
|
|
f3cbb9 |
|
|
|
f3cbb9 |
if (onFinished)
|
|
|
f3cbb9 |
onFinished();
|
|
|
f3cbb9 |
return;
|
|
|
f3cbb9 |
}
|
|
|
f3cbb9 |
|
|
|
f3cbb9 |
let isNewObject;
|
|
|
f3cbb9 |
if (!this._objects[objectPath]) {
|
|
|
f3cbb9 |
this._objects[objectPath] = {};
|
|
|
f3cbb9 |
isNewObject = true;
|
|
|
f3cbb9 |
} else {
|
|
|
f3cbb9 |
isNewObject = false;
|
|
|
f3cbb9 |
}
|
|
|
f3cbb9 |
|
|
|
f3cbb9 |
this._objects[objectPath][interfaceName] = proxy;
|
|
|
f3cbb9 |
|
|
|
f3cbb9 |
if (!this._interfaces[interfaceName])
|
|
|
f3cbb9 |
this._interfaces[interfaceName] = [];
|
|
|
f3cbb9 |
|
|
|
f3cbb9 |
this._interfaces[interfaceName].push(proxy);
|
|
|
f3cbb9 |
|
|
|
f3cbb9 |
@@ -154,92 +157,119 @@ const ObjectManager = new Lang.Class({
|
|
|
f3cbb9 |
},
|
|
|
f3cbb9 |
|
|
|
f3cbb9 |
_onManagerProxyLoaded: function(initable, result) {
|
|
|
f3cbb9 |
let error = null;
|
|
|
f3cbb9 |
try {
|
|
|
f3cbb9 |
initable.init_finish(result);
|
|
|
f3cbb9 |
} catch(e) {
|
|
|
f3cbb9 |
logError(e, 'could not initialize object manager for object ' + params.name);
|
|
|
f3cbb9 |
|
|
|
f3cbb9 |
this._tryToCompleteLoad();
|
|
|
f3cbb9 |
return;
|
|
|
f3cbb9 |
}
|
|
|
f3cbb9 |
|
|
|
f3cbb9 |
this._managerProxy.connectSignal('InterfacesAdded',
|
|
|
f3cbb9 |
Lang.bind(this, function(objectManager, sender, [objectPath, interfaces]) {
|
|
|
f3cbb9 |
let interfaceNames = Object.keys(interfaces);
|
|
|
f3cbb9 |
for (let i = 0; i < interfaceNames.length; i++)
|
|
|
f3cbb9 |
this._addInterface(objectPath, interfaceNames[i]);
|
|
|
f3cbb9 |
}));
|
|
|
f3cbb9 |
this._managerProxy.connectSignal('InterfacesRemoved',
|
|
|
f3cbb9 |
Lang.bind(this, function(objectManager, sender, [objectPath, interfaceNames]) {
|
|
|
f3cbb9 |
for (let i = 0; i < interfaceNames.length; i++)
|
|
|
f3cbb9 |
this._removeInterface(objectPath, interfaceNames[i]);
|
|
|
f3cbb9 |
}));
|
|
|
f3cbb9 |
|
|
|
f3cbb9 |
if (Object.keys(this._interfaceInfos).length == 0) {
|
|
|
f3cbb9 |
this._tryToCompleteLoad();
|
|
|
f3cbb9 |
return;
|
|
|
f3cbb9 |
}
|
|
|
f3cbb9 |
|
|
|
f3cbb9 |
+ this._managerProxy.connect('notify::g-name-owner', Lang.bind(this, function() {
|
|
|
f3cbb9 |
+ if (this._managerProxy.g_name_owner)
|
|
|
f3cbb9 |
+ this._onNameAppeared();
|
|
|
f3cbb9 |
+ else
|
|
|
f3cbb9 |
+ this._onNameVanished();
|
|
|
f3cbb9 |
+ }));
|
|
|
f3cbb9 |
+
|
|
|
f3cbb9 |
+ if (this._managerProxy.g_name_owner)
|
|
|
f3cbb9 |
+ this._onNameAppeared();
|
|
|
f3cbb9 |
+ },
|
|
|
f3cbb9 |
+
|
|
|
f3cbb9 |
+ _onNameAppeared: function() {
|
|
|
f3cbb9 |
this._managerProxy.GetManagedObjectsRemote(Lang.bind(this, function(result, error) {
|
|
|
f3cbb9 |
if (!result) {
|
|
|
f3cbb9 |
if (error) {
|
|
|
f3cbb9 |
logError(error, 'could not get remote objects for service ' + this._serviceName + ' path ' + this._managerPath);
|
|
|
f3cbb9 |
}
|
|
|
f3cbb9 |
|
|
|
f3cbb9 |
this._tryToCompleteLoad();
|
|
|
f3cbb9 |
return;
|
|
|
f3cbb9 |
}
|
|
|
f3cbb9 |
|
|
|
f3cbb9 |
let [objects] = result;
|
|
|
f3cbb9 |
|
|
|
f3cbb9 |
let objectPaths = Object.keys(objects);
|
|
|
f3cbb9 |
for (let i = 0; i < objectPaths.length; i++) {
|
|
|
f3cbb9 |
let objectPath = objectPaths[i];
|
|
|
f3cbb9 |
let object = objects[objectPath];
|
|
|
f3cbb9 |
|
|
|
f3cbb9 |
let interfaceNames = Object.getOwnPropertyNames(object);
|
|
|
f3cbb9 |
for (let j = 0; j < interfaceNames.length; j++) {
|
|
|
f3cbb9 |
let interfaceName = interfaceNames[j];
|
|
|
f3cbb9 |
|
|
|
f3cbb9 |
// Prevent load from completing until the interface is loaded
|
|
|
f3cbb9 |
this._numLoadInhibitors++;
|
|
|
f3cbb9 |
this._addInterface(objectPath,
|
|
|
f3cbb9 |
interfaceName,
|
|
|
f3cbb9 |
Lang.bind(this, this._tryToCompleteLoad));
|
|
|
f3cbb9 |
}
|
|
|
f3cbb9 |
}
|
|
|
f3cbb9 |
this._tryToCompleteLoad();
|
|
|
f3cbb9 |
}));
|
|
|
f3cbb9 |
},
|
|
|
f3cbb9 |
|
|
|
f3cbb9 |
+ _onNameVanished: function() {
|
|
|
f3cbb9 |
+ let objectPaths = Object.keys(this._objects);
|
|
|
f3cbb9 |
+ for (let i = 0; i < objectPaths.length; i++) {
|
|
|
f3cbb9 |
+ let object = this._objects[objectPaths];
|
|
|
f3cbb9 |
+
|
|
|
f3cbb9 |
+ let interfaceNames = Object.keys(object);
|
|
|
f3cbb9 |
+ for (let j = 0; i < interfaceNames.length; i++) {
|
|
|
f3cbb9 |
+ let interfaceName = interfaceNames[i];
|
|
|
f3cbb9 |
+
|
|
|
f3cbb9 |
+ if (object[interfaceName])
|
|
|
f3cbb9 |
+ this._removeInterface(objectPath, interfaceName);
|
|
|
f3cbb9 |
+ }
|
|
|
f3cbb9 |
+ }
|
|
|
f3cbb9 |
+ },
|
|
|
f3cbb9 |
+
|
|
|
f3cbb9 |
_registerInterfaces: function(interfaces) {
|
|
|
f3cbb9 |
for (let i = 0; i < interfaces.length; i++) {
|
|
|
f3cbb9 |
let info = Gio.DBusInterfaceInfo.new_for_xml(interfaces[i]);
|
|
|
f3cbb9 |
this._interfaceInfos[info.name] = info;
|
|
|
f3cbb9 |
}
|
|
|
f3cbb9 |
},
|
|
|
f3cbb9 |
|
|
|
f3cbb9 |
getProxy: function(objectPath, interfaceName) {
|
|
|
f3cbb9 |
let object = this._objects[objectPath];
|
|
|
f3cbb9 |
|
|
|
f3cbb9 |
if (!object)
|
|
|
f3cbb9 |
return null;
|
|
|
f3cbb9 |
|
|
|
f3cbb9 |
return object[interfaceName];
|
|
|
f3cbb9 |
},
|
|
|
f3cbb9 |
|
|
|
f3cbb9 |
getProxiesForInterface: function(interfaceName) {
|
|
|
f3cbb9 |
let proxyList = this._interfaces[interfaceName];
|
|
|
f3cbb9 |
|
|
|
f3cbb9 |
if (!proxyList)
|
|
|
f3cbb9 |
return [];
|
|
|
f3cbb9 |
|
|
|
f3cbb9 |
return proxyList;
|
|
|
f3cbb9 |
},
|
|
|
f3cbb9 |
|
|
|
f3cbb9 |
getAllProxies: function() {
|
|
|
f3cbb9 |
let proxies = [];
|
|
|
f3cbb9 |
|
|
|
f3cbb9 |
let objectPaths = Object.keys(this._objects);
|
|
|
f3cbb9 |
for (let i = 0; i < objectPaths.length; i++) {
|