[polari] accountsMonitor: Add :reachable account property



commit f32b45a8be40ef52ea2cc33b7bdfc3051d2fff52
Author: Florian Müllner <fmuellner gnome org>
Date:   Sun May 12 07:28:45 2019 +0200

    accountsMonitor: Add :reachable account property
    
    The property reflects whether at least one of the account's servers
    can be reached. This will allow for a much less erroneous connectivity
    handling than the rather coarse GNetworkManager:network-available.
    
    https://gitlab.gnome.org/GNOME/polari/merge_requests/120

 src/accountsMonitor.js | 71 ++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 69 insertions(+), 2 deletions(-)
---
diff --git a/src/accountsMonitor.js b/src/accountsMonitor.js
index 71f1dc7..795a206 100644
--- a/src/accountsMonitor.js
+++ b/src/accountsMonitor.js
@@ -16,6 +16,8 @@ var AccountsMonitor = class {
         this._accounts = new Map();
         this._accountSettings = new Map();
 
+        this._networkMonitor = Gio.NetworkMonitor.get_default();
+
         this._app = Gio.Application.get_default();
 
         if (!this._app.isTestInstance) {
@@ -85,10 +87,12 @@ var AccountsMonitor = class {
         am.dup_valid_accounts().forEach(this._addAccount.bind(this));
 
         am.connect('account-validity-changed', (am, account, valid) => {
-            if (valid)
+            if (valid) {
                 this._addAccount(account);
-            else
+                this._updateAccountReachable(account);
+            } else {
                 this._removeAccount(account);
+            }
         });
         am.connect('account-removed', (am, account) => {
             this._removeAccount(account);
@@ -97,6 +101,14 @@ var AccountsMonitor = class {
         am.connect('account-disabled', this._accountEnabledChanged.bind(this));
 
         this._preparedCallbacks.forEach(callback => callback());
+
+        this._networkMonitor.connect('network-changed',
+            this._onNetworkChanged.bind(this));
+        this._onNetworkChanged();
+    }
+
+    _onNetworkChanged() {
+        this.visibleAccounts.forEach(a => this._updateAccountReachable(a));
     }
 
     _onPrepareShutdown() {
@@ -127,8 +139,13 @@ var AccountsMonitor = class {
             account.connect('notify::connection-status', () => {
                 this.emit('account-status-changed', account);
             });
+        account._reachableNotifyId =
+            account.connect('notify::reachable', () => {
+                this.emit('account-reachable-changed', account);
+            });
         account._visibleNotifyId =
             account.connect('notify::visible', () => {
+                this._updateAccountReachable(account);
                 let signal = account.visible ?
                     'account-shown' : 'account-hidden';
                 this.emit(signal, account);
@@ -147,6 +164,9 @@ var AccountsMonitor = class {
         account.disconnect(account._statusNotifyId);
         delete account._statusNotifyId;
 
+        account.disconnect(account._reachableNotifyId);
+        delete account._reachableNotifyId;
+
         account.disconnect(account._visibleNotifyId);
         delete account._visibleNotifyId;
 
@@ -161,6 +181,36 @@ var AccountsMonitor = class {
         this.emit(signal, account);
         this.emit('accounts-changed');
     }
+
+    async _updateAccountReachable(account) {
+        if (!this._networkMonitor.state_valid)
+            return;
+
+        let servers = account.getServers();
+        for (let s of servers) {
+            let addr = new Gio.NetworkAddress({
+                hostname: s.address,
+                port: s.port
+            });
+
+            account._setReachable(await this._canReach(addr));
+
+            if (account.reachable)
+                break;
+        }
+    }
+
+    _canReach(addr) {
+        return new Promise((resolve) => {
+            this._networkMonitor.can_reach_async(addr, null, (mon, res) => {
+                try {
+                    resolve(this._networkMonitor.can_reach_finish(res));
+                } catch (e) {
+                    resolve(false);
+                }
+            });
+        });
+    }
 };
 Signals.addSignalMethods(AccountsMonitor.prototype);
 
@@ -182,6 +232,10 @@ const PolariAccount = GObject.registerClass({
             'predefined', 'predefined', 'predefined',
             GObject.ParamFlags.READABLE,
             false),
+        reachable: GObject.ParamSpec.boolean(
+            'reachable', 'reachable', 'reachable',
+            GObject.ParamFlags.READABLE,
+            false),
         visible: GObject.ParamSpec.boolean(
             'visible', 'visible', 'visible',
             GObject.ParamFlags.READWRITE,
@@ -190,6 +244,7 @@ const PolariAccount = GObject.registerClass({
 }, class PolariAccount extends Tp.Account {
     _init(params) {
         this._visible = true;
+        this._reachable = undefined;
 
         this._networksManager = NetworksManager.getDefault();
 
@@ -200,6 +255,18 @@ const PolariAccount = GObject.registerClass({
         return this._networksManager.getAccountIsPredefined(this);
     }
 
+    get reachable() {
+        return this._reachable;
+    }
+
+    _setReachable(reachable) {
+        if (this._reachable == reachable)
+            return;
+
+        this._reachable = reachable;
+        this.notify('reachable');
+    }
+
     get visible() {
         return this._visible;
     }


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