Skip to content

Commit

Permalink
breaking: make low-level interface private
Browse files Browse the repository at this point in the history
Make low-level dbus invokations and internal bus properties private
including the `connection`. Add `bus.disconnect()` to disconnect from
the bus in tests.
  • Loading branch information
Tony Crisci committed Mar 30, 2019
1 parent 7e408a9 commit 3da2739
Show file tree
Hide file tree
Showing 14 changed files with 123 additions and 123 deletions.
152 changes: 76 additions & 76 deletions lib/bus.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,22 +15,21 @@ let { Interface } = require('./service/interface');

class Bus {
constructor(conn) {
this.connection = conn;
this.serial = 1;
this.cookies = {}; // TODO: rename to methodReturnHandlers
this.signals = new EventEmitter();
this.exportedObjects = {};
this._connection = conn;
this._serial = 1;
this._methodReturnHandlers = {};
this._signals = new EventEmitter();
this._names = {};
this.nameOwners = {};
this._nameOwners = {};

let handleMessage = (msg) => {
if (msg.type === constants.messageType.methodReturn ||
msg.type === constants.messageType.error) {
let handler = this.cookies[msg.replySerial];
let handler = this._methodReturnHandlers[msg.replySerial];
if (handler) {
delete this.cookies[msg.replySerial];
delete this._methodReturnHandlers[msg.replySerial];
let props = {
connection: this.connection,
connection: this._connection,
bus: this,
message: msg,
signature: msg.signature
Expand All @@ -52,15 +51,20 @@ class Bus {
member === 'NameOwnerChanged') {
let [name, oldOwner, newOwner] = msg.body;
if (!name.startsWith(':')) {
this.nameOwners[name] = newOwner;
this._nameOwners[name] = newOwner;
}
}

this.signals.emit(this.mangle(msg), msg);
let mangled = JSON.stringify({
path: msg.path,
'interface': msg['interface'],
member: msg.member
});
this._signals.emit(mangled, msg);
} else {
// methodCall
if (!handleMethod(msg, this)) {
this.sendError(msg,
this._sendError(msg,
'org.freedesktop.DBus.Error.UnknownMethod',
`Method '${msg.member}' on interface '${msg.interface}' does not exist`);
}
Expand All @@ -71,28 +75,66 @@ class Bus {
try {
handleMessage(msg);
} catch (e) {
this.sendError(msg, 'com.github.dbus_next.Error', `The DBus library encountered an error.\n${e.stack}`);
this._sendError(msg, 'com.github.dbus_next.Error', `The DBus library encountered an error.\n${e.stack}`);
}
});

this.invokeDbus({ member: 'Hello' }, (err, name) => {
this._invokeDbus({ member: 'Hello' }, (err, name) => {
if (err) {
throw new Error(err);
}
this.name = name;
});
}

invoke(msg, callback) {
getProxyObject(name, path) {
let obj = new ProxyObject(this, name, path);
return obj._init();
};

requestName(name, flags) {
flags = flags || 0;
return new Promise((resolve, reject) => {
assertBusNameValid(name);
let dbusRequest = {
member: 'RequestName',
signature: 'su',
body: [name, flags]
};
this._invokeDbus(dbusRequest, (err, result) => {
if (err) {
return reject(err);
}
if (result === constants.DBUS_REQUEST_NAME_REPLY_EXISTS) {
return reject(new NameExistsError(`the name already exists: ${name}`));
}
if (this._names[name]) {
let nameObj = this._names[name];
nameObj.flags = flags;
return resolve(nameObj);
}
let nameObj = new Name(this, name, flags);
this._names[name] = nameObj;
return resolve(nameObj);
}
);
});
};

disconnect() {
this._connection.stream.end();
}

_invoke(msg, callback) {
if (!msg.type) {
msg.type = constants.messageType.methodCall;
}
msg.serial = this.serial++;
this.cookies[msg.serial] = callback;
this.connection.message(msg);
msg.serial = this._serial++;
this._methodReturnHandlers[msg.serial] = callback;
this._connection.message(msg);
};

invokeDbus(msg, callback) {
_invokeDbus(msg, callback) {
if (!msg.path) {
msg.path = '/org/freedesktop/DBus';
}
Expand All @@ -102,21 +144,13 @@ class Bus {
if (!msg['interface']) {
msg['interface'] = 'org.freedesktop.DBus';
}
this.invoke(msg, callback);
this._invoke(msg, callback);
};

mangle(msg) {
return JSON.stringify({
path: msg.path,
'interface': msg['interface'],
member: msg.member
});
};

sendSignal(path, iface, name, signature, args) {
_sendSignal(path, iface, name, signature, args) {
let msg = {
type: constants.messageType.signal,
serial: this.serial++,
serial: this._serial++,
interface: iface,
path: path,
member: name
Expand All @@ -125,14 +159,14 @@ class Bus {
msg.signature = signature;
msg.body = args;
}
this.connection.message(msg);
this._connection.message(msg);
};

// Warning: errorName must respect the same rules as interface names (must contain a dot)
sendError(msg, errorName, errorText) {
this.connection.message({
_sendError(msg, errorName, errorText) {
this._connection.message({
type: constants.messageType.error,
serial: this.serial++,
serial: this._serial++,
replySerial: msg.serial,
destination: msg.sender,
errorName: errorName,
Expand All @@ -141,70 +175,36 @@ class Bus {
});
};

sendReply(msg, signature, body) {
this.connection.message({
_sendReply(msg, signature, body) {
this._connection.message({
type: constants.messageType.methodReturn,
serial: this.serial++,
serial: this._serial++,
replySerial: msg.serial,
destination: msg.sender,
signature: signature,
body: body
});
};

getProxyObject(name, path) {
let obj = new ProxyObject(this, name, path);
return obj._init();
};

addMatch(match, callback) {
this.invokeDbus(
_addMatch(match, callback) {
this._invokeDbus(
{ member: 'AddMatch', signature: 's', body: [match] },
callback
);
};

requestName(name, flags) {
flags = flags || 0;
return new Promise((resolve, reject) => {
assertBusNameValid(name);
let dbusRequest = {
member: 'RequestName',
signature: 'su',
body: [name, flags]
};
this.invokeDbus(dbusRequest, (err, result) => {
if (err) {
return reject(err);
}
if (result === constants.DBUS_REQUEST_NAME_REPLY_EXISTS) {
return reject(new NameExistsError(`the name already exists: ${name}`));
}
if (this._names[name]) {
let nameObj = this._names[name];
nameObj.flags = flags;
return resolve(nameObj);
}
let nameObj = new Name(this, name, flags);
this._names[name] = nameObj;
return resolve(nameObj);
}
);
});
};

getNameOwner(name) {
_getNameOwner(name) {
return new Promise((resolve, reject) => {
let msg = {
member: 'GetNameOwner',
signature: 's',
body: [name]
};
this.invokeDbus(msg, (err, owner) => {
this._invokeDbus(msg, (err, owner) => {
if (err) {
return reject(err);
}
this.nameOwners[name] = owner;
this._nameOwners[name] = owner;
return resolve(owner);
});
});
Expand Down
12 changes: 6 additions & 6 deletions lib/client/proxy-object.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,16 +44,16 @@ class ProxyObject {
let iface = ProxyInterface._fromXml(this, i);
if (iface !== null) {
this.interfaces.push(iface);
this.bus.addMatch(`type='signal',sender=${this.name},interface='${iface.$name}',path='${this.path}'`);
this.bus._addMatch(`type='signal',sender=${this.name},interface='${iface.$name}',path='${this.path}'`);
for (let signal of iface.$signals) {
let event = JSON.stringify({
path: this.path,
interface: iface.$name,
member: signal.name
});
this.bus.signals.on(event, (msg) => {
this.bus._signals.on(event, (msg) => {
let {body, signature, sender} = msg;
if (this.bus.nameOwners[this.name] !== sender) {
if (this.bus._nameOwners[this.name] !== sender) {
return;
}
if (signature !== signal.signature) {
Expand All @@ -77,7 +77,7 @@ class ProxyObject {

_init() {
let introspect = new Promise((resolve, reject) => {
this.bus.invoke(
this.bus._invoke(
{
destination: this.name,
path: this.path,
Expand Down Expand Up @@ -105,7 +105,7 @@ class ProxyObject {
});

return new Promise((resolve, reject) => {
Promise.all([introspect, this.bus.getNameOwner(this.name)])
Promise.all([introspect, this.bus._getNameOwner(this.name)])
.then((result) => {
return resolve(result[0]);
})
Expand Down Expand Up @@ -146,7 +146,7 @@ class ProxyObject {
body: body
};

this.bus.invoke(msg, function(err, ...busResult) {
this.bus._invoke(msg, function(err, ...busResult) {
if (err) {
if (this.message && this.message.hasOwnProperty('errorName')) {
reject(new DBusError(this.message.errorName, err[0]));
Expand Down
Loading

0 comments on commit 3da2739

Please sign in to comment.