1 /*
2  * This file is part of signon
3  *
4  * Copyright (C) 2009-2010 Nokia Corporation.
5  * Copyright (C) 2013-2016 Canonical Ltd.
6  *
7  * Contact: Alberto Mardegan <alberto.mardegan@canonical.com>
8  *
9  * This library is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public License
11  * version 2.1 as published by the Free Software Foundation.
12  *
13  * This library is distributed in the hope that it will be useful, but
14  * WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
21  * 02110-1301 USA
22  */
23 
24 #ifndef SIGNON_ASYNC_DBUS_PROXY_H
25 #define SIGNON_ASYNC_DBUS_PROXY_H
26 
27 #include <QDBusError>
28 #include <QObject>
29 #include <QQueue>
30 #include <QVariant>
31 
32 class QDBusAbstractInterface;
33 class QDBusConnection;
34 class QDBusObjectPath;
35 class QDBusPendingCallWatcher;
36 
37 /*
38  * @cond IMPL
39  */
40 namespace SignOn {
41 
42 class AsyncDBusProxy;
43 class Connection;
44 class DBusInterface;
45 
46 class PendingCall: public QObject
47 {
48     Q_OBJECT
49 
50 public:
51     ~PendingCall();
52 
53     bool cancel();
54 
55 Q_SIGNALS:
56     void finished(QDBusPendingCallWatcher *watcher);
57     void success(QDBusPendingCallWatcher *watcher);
58     void error(const QDBusError &error);
59     void requeueRequested();
60 
61 private Q_SLOTS:
62     void onFinished(QDBusPendingCallWatcher *watcher);
63     void onInterfaceDestroyed();
64     void fail(const QDBusError &error);
65 
66 private:
67     friend class AsyncDBusProxy;
68     PendingCall(const QString &method,
69                 const QList<QVariant> &args,
70                 QObject *parent = 0);
71     void doCall(QDBusAbstractInterface *interface);
72 
73 private:
74     QString m_method;
75     QList<QVariant> m_args;
76     QDBusPendingCallWatcher *m_watcher;
77     bool m_interfaceWasDestroyed;
78 };
79 
80 class AsyncDBusProxy: public QObject
81 {
82     Q_OBJECT
83 
84 public:
85     AsyncDBusProxy(const QString &service,
86                    const char *interface,
87                    QObject *clientObject);
88     ~AsyncDBusProxy();
89 
90     void setObjectPath(const QDBusObjectPath &objectPath);
91     void setError(const QDBusError &error);
92 
93     PendingCall *queueCall(const QString &method,
94                            const QList<QVariant> &args,
95                            const char *replySlot = 0,
96                            const char *errorSlot = 0);
97     PendingCall *queueCall(const QString &method,
98                            const QList<QVariant> &args,
99                            QObject *receiver,
100                            const char *replySlot,
101                            const char *errorSlot);
102     bool connect(const char *name, QObject *receiver, const char *slot);
103 
104 public Q_SLOTS:
105     void setConnection(const QDBusConnection &connection);
106     void setDisconnected();
107 
108 Q_SIGNALS:
109     void connectionNeeded();
110     void objectPathNeeded();
111 
112 private:
113     enum Status {
114         Incomplete,
115         Ready,
116         Invalid
117     };
118     void setStatus(Status status);
119     void update();
120     void enqueue(PendingCall *call);
121 
122 private Q_SLOTS:
123     void onCallFinished(QDBusPendingCallWatcher *watcher);
124     void onRequeueRequested();
125 
126 private:
127     QString m_serviceName;
128     const char *m_interfaceName;
129     QString m_path;
130     QDBusConnection *m_connection;
131     QObject *m_clientObject;
132     QQueue<PendingCall *> m_operationsQueue;
133     QQueue<Connection *> m_connectionsQueue;
134     DBusInterface *m_interface;
135     Status m_status;
136     QDBusError m_lastError;
137 };
138 
139 class SignondAsyncDBusProxy: public AsyncDBusProxy
140 {
141     Q_OBJECT
142 public:
143     SignondAsyncDBusProxy(const char *interface,
144                           QObject *clientObject);
145     ~SignondAsyncDBusProxy();
146 
147 private:
148     void setupConnection();
149 };
150 
151 } //SignOn
152 
153 /*
154  * @endcond IMPL
155  */
156 
157 #endif // SIGNON_ASYNC_DBUS_PROXY_H
158