dbusProxy.js 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. import Gio from 'gi://Gio';
  2. import GLib from 'gi://GLib';
  3. import GObject from 'gi://GObject';
  4. import {CancellableChild, Logger} from './util.js';
  5. Gio._promisify(Gio.DBusProxy.prototype, 'init_async');
  6. export const DBusProxy = GObject.registerClass({
  7. Signals: {'destroy': {}},
  8. }, class DBusProxy extends Gio.DBusProxy {
  9. static get TUPLE_VARIANT_TYPE() {
  10. if (!this._tupleVariantType)
  11. this._tupleVariantType = new GLib.VariantType('(v)');
  12. return this._tupleVariantType;
  13. }
  14. static destroy() {
  15. delete this._tupleType;
  16. }
  17. _init(busName, objectPath, interfaceInfo, flags = Gio.DBusProxyFlags.NONE) {
  18. if (interfaceInfo.signals.length)
  19. Logger.warn('Avoid exposing signals to gjs!');
  20. super._init({
  21. gConnection: Gio.DBus.session,
  22. gInterfaceName: interfaceInfo.name,
  23. gInterfaceInfo: interfaceInfo,
  24. gName: busName,
  25. gObjectPath: objectPath,
  26. gFlags: flags,
  27. });
  28. this._signalIds = [];
  29. if (!(flags & Gio.DBusProxyFlags.DO_NOT_CONNECT_SIGNALS)) {
  30. this._signalIds.push(this.connect('g-signal',
  31. (_proxy, ...args) => this._onSignal(...args)));
  32. }
  33. this._signalIds.push(this.connect('notify::g-name-owner', () =>
  34. this._onNameOwnerChanged()));
  35. }
  36. async initAsync(cancellable) {
  37. cancellable = new CancellableChild(cancellable);
  38. await this.init_async(GLib.PRIORITY_DEFAULT, cancellable);
  39. this._cancellable = cancellable;
  40. this.gInterfaceInfo.methods.map(m => m.name).forEach(method =>
  41. this._ensureAsyncMethod(method));
  42. }
  43. destroy() {
  44. this.emit('destroy');
  45. this._signalIds.forEach(id => this.disconnect(id));
  46. if (this._cancellable)
  47. this._cancellable.cancel();
  48. }
  49. // This can be removed when we will have GNOME 43 as minimum version
  50. _ensureAsyncMethod(method) {
  51. if (this[`${method}Async`])
  52. return;
  53. if (!this[`${method}Remote`])
  54. throw new Error(`Missing remote method '${method}'`);
  55. this[`${method}Async`] = function (...args) {
  56. return new Promise((resolve, reject) => {
  57. this[`${method}Remote`](...args, (ret, e) => {
  58. if (e)
  59. reject(e);
  60. else
  61. resolve(ret);
  62. });
  63. });
  64. };
  65. }
  66. _onSignal() {
  67. }
  68. getProperty(propertyName, cancellable) {
  69. return this.gConnection.call(this.gName,
  70. this.gObjectPath, 'org.freedesktop.DBus.Properties', 'Get',
  71. GLib.Variant.new('(ss)', [this.gInterfaceName, propertyName]),
  72. DBusProxy.TUPLE_VARIANT_TYPE, Gio.DBusCallFlags.NONE, -1,
  73. cancellable);
  74. }
  75. getProperties(cancellable) {
  76. return this.gConnection.call(this.gName,
  77. this.gObjectPath, 'org.freedesktop.DBus.Properties', 'GetAll',
  78. GLib.Variant.new('(s)', [this.gInterfaceName]),
  79. GLib.VariantType.new('(a{sv})'), Gio.DBusCallFlags.NONE, -1,
  80. cancellable);
  81. }
  82. });