[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-commits
Subject:    KDE/kdenetwork/krfb/krfb
From:       George Kiagiadakis <kiagiadakis.george () gmail ! com>
Date:       2010-11-10 18:57:33
Message-ID: 20101110185733.5F77EAC8A2 () svn ! kde ! org
[Download RAW message or body]

SVN commit 1195292 by gkiagia:

Fix the broken clients design.

Currently clients are not connected immediately because the user needs
to be notified and take action upon the connection request. This makes
the design of the RfbClient class a bit strange. This new approach
applies tp-qt4's PendingOperation design to RfbClients. New connections
create a PendingRfbClient that internally handles the user notification
and the RfbClient object is only created when the user has accepted the
connection.

 M  +2 -0      CMakeLists.txt  
 A             invitationsrfbclient.cpp   invitationsrfbserver.cpp#1195291 [License: \
GPL (v2+)]  A             invitationsrfbclient.h   invitationsrfbserver.h#1195291 \
[License: GPL (v2+)]  M  +4 -74     invitationsrfbserver.cpp  
 M  +1 -1      invitationsrfbserver.h  
 A             pendingrfbclient.cpp   [License: LGPL (v2.1+)]
 A             pendingrfbclient.h   [License: LGPL (v2.1+)]
 M  +53 -67    rfbclient.cpp  
 M  +25 -9     rfbclient.h  
 M  +12 -6     rfbserver.cpp  
 M  +2 -1      rfbserver.h  
 M  +1 -4      rfbservermanager.cpp  
 A             tubesrfbclient.cpp   [License: GPL (v2+)]
 A             tubesrfbclient.h   [License: GPL (v2+)]
 M  +4 -64     tubesrfbserver.cpp  
 M  +1 -1      tubesrfbserver.h  


--- trunk/KDE/kdenetwork/krfb/krfb/CMakeLists.txt #1195291:1195292
@@ -61,12 +61,14 @@
      rfbserver.cpp
      rfbclient.cpp
      invitationsrfbserver.cpp
+     invitationsrfbclient.cpp
 )
 
 if (TELEPATHY_QT4_FOUND)
     set (krfb_SRCS
          ${krfb_SRCS}
          tubesrfbserver.cpp
+         tubesrfbclient.cpp
          tubesclienthandler.cpp
     )
 endif (TELEPATHY_QT4_FOUND)
--- trunk/KDE/kdenetwork/krfb/krfb/invitationsrfbserver.cpp #1195291:1195292
@@ -19,10 +19,11 @@
     along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 #include "invitationsrfbserver.h"
+#include "invitationsrfbclient.h"
 #include "krfbconfig.h"
-#include "invitationmanager.h"
 #include "rfbservermanager.h"
 #include <QtCore/QTimer>
+#include <QtGui/QApplication>
 #include <QtNetwork/QHostInfo>
 #include <KNotification>
 #include <KLocale>
@@ -30,77 +31,6 @@
 #include <KUser>
 #include <DNSSD/PublicService>
 
-//************
-
-class InvitationsRfbClient : public RfbClient
-{
-public:
-    InvitationsRfbClient(rfbClientPtr client, QObject* parent = 0)
-        : RfbClient(client, parent) {}
-
-    virtual rfbNewClientAction doHandle();
-    virtual bool checkPassword(const QByteArray & encryptedPassword);
-};
-
-rfbNewClientAction InvitationsRfbClient::doHandle()
-{
-    bool allowUninvited = KrfbConfig::allowUninvitedConnections();
-
-    if (!allowUninvited && InvitationManager::self()->activeInvitations() == 0) {
-        KNotification::event("UnexpectedConnection",
-                             i18n("Refused uninvited connection attempt from %1", \
                name()));
-        return RFB_CLIENT_REFUSE;
-    }
-
-    return RfbClient::doHandle();
-}
-
-bool InvitationsRfbClient::checkPassword(const QByteArray & encryptedPassword)
-{
-    bool allowUninvited = KrfbConfig::allowUninvitedConnections();
-    QByteArray password =  KrfbConfig::uninvitedConnectionPassword().toLocal8Bit();
-
-    bool authd = false;
-    kDebug() << "about to start autentication";
-
-    if (allowUninvited) {
-        authd = vncAuthCheckPassword(password, encryptedPassword);
-    }
-
-    if (!authd) {
-        QList<Invitation> invlist = InvitationManager::self()->invitations();
-
-        foreach(const Invitation & it, invlist) {
-            kDebug() << "checking password";
-
-            if (vncAuthCheckPassword(it.password().toLocal8Bit(), encryptedPassword)
-                && it.isValid())
-            {
-                authd = true;
-                InvitationManager::self()->removeInvitation(it);
-                break;
-            }
-        }
-    }
-
-    if (!authd) {
-        if (InvitationManager::self()->invitations().size() > 0) {
-            KNotification::event("InvalidPasswordInvitations",
-                                 i18n("Failed login attempt from %1: wrong \
                password", name()));
-        } else {
-            KNotification::event("InvalidPassword",
-                                 i18n("Failed login attempt from %1: wrong \
                password", name()));
-        }
-
-        return false;
-    }
-
-    return true;
-}
-
-//***********
-
-
 void InvitationsRfbServer::init()
 {
     InvitationsRfbServer *server;
@@ -111,9 +41,9 @@
     QTimer::singleShot(0, server, SLOT(startAndCheck()));
 }
 
-RfbClient* InvitationsRfbServer::newClient(rfbClientPtr client)
+PendingRfbClient* InvitationsRfbServer::newClient(rfbClientPtr client)
 {
-    return new InvitationsRfbClient(client, this);
+    return new PendingInvitationsRfbClient(client, this);
 }
 
 void InvitationsRfbServer::startAndCheck()
--- trunk/KDE/kdenetwork/krfb/krfb/invitationsrfbserver.h #1195291:1195292
@@ -31,7 +31,7 @@
 protected:
     InvitationsRfbServer() : RfbServer(0) {}
 
-    virtual RfbClient* newClient(rfbClientPtr client);
+    virtual PendingRfbClient* newClient(rfbClientPtr client);
 
 private Q_SLOTS:
     void startAndCheck();
--- trunk/KDE/kdenetwork/krfb/krfb/rfbclient.cpp #1195291:1195292
@@ -30,12 +30,10 @@
 struct RfbClient::Private
 {
     Private(rfbClientPtr client) :
-        connected(false),
         controlEnabled(false),
         client(client)
     {}
 
-    bool connected;
     bool controlEnabled;
     rfbClientPtr client;
     QSocketNotifier *notifier;
@@ -79,28 +77,19 @@
     }
 }
 
-void RfbClient::update()
+bool RfbClient::isOnHold() const
 {
-    rfbUpdateClient(d->client);
-
-    //This is how we handle disconnection.
-    //if rfbUpdateClient() finds out that it can't write to the socket,
-    //it closes it and sets it to -1. So, we just have to check this here
-    //and call rfbClientConnectionGone() if necessary. This will call
-    //the clientGoneHook which in turn will remove this RfbClient instance
-    //from the server manager and will call deleteLater() to delete it
-    if (d->client->sock == -1) {
-        kDebug() << "disconnected during update";
-        d->notifier->setEnabled(false);
-        rfbClientConnectionGone(d->client);
+    return d->client->onHold ? true : false;
     }
-}
 
 void RfbClient::setOnHold(bool onHold)
 {
+    if (isOnHold() != onHold) {
     d->client->onHold = onHold;
     d->notifier->setEnabled(!onHold);
+        Q_EMIT holdStatusChanged(onHold);
 }
+}
 
 void RfbClient::closeConnection()
 {
@@ -109,47 +98,6 @@
     rfbClientConnectionGone(d->client);
 }
 
-rfbNewClientAction RfbClient::doHandle()
-{
-    kDebug();
-
-    if (!KrfbConfig::askOnConnect()) {
-        KNotification::event("NewConnectionAutoAccepted",
-                             i18n("Accepted connection from %1", name()));
-
-        setStatusConnected();
-        return RFB_CLIENT_ACCEPT;
-    }
-
-    KNotification::event("NewConnectionOnHold",
-                         i18n("Received connection from %1, on hold (waiting for \
                confirmation)",
-                              name()));
-
-    ConnectionDialog *dialog = new ConnectionDialog(0);
-    dialog->setRemoteHost(name());
-    dialog->setAllowRemoteControl(KrfbConfig::allowDesktopControl());
-
-    connect(dialog, SIGNAL(okClicked()), SLOT(dialogAccepted()));
-    connect(dialog, SIGNAL(cancelClicked()), SLOT(dialogRejected()));
-
-    dialog->show();
-
-    return RFB_CLIENT_ON_HOLD;
-}
-
-bool RfbClient::isConnected() const
-{
-    return d->connected;
-}
-
-void RfbClient::setStatusConnected()
-{
-    if (!d->connected) {
-        d->connected = true;
-        Q_EMIT connected(this);
-    }
-}
-
 void RfbClient::handleKeyboardEvent(bool down, rfbKeySym keySym)
 {
     if (d->controlEnabled) {
@@ -218,24 +166,62 @@
     }
 }
 
-void RfbClient::dialogAccepted()
+void RfbClient::update()
 {
-    ConnectionDialog *dialog = qobject_cast<ConnectionDialog *>(sender());
+    rfbUpdateClient(d->client);
 
-    if (!dialog) {
-        kWarning() << "Wrong type of sender.";
-        return;
+    //This is how we handle disconnection.
+    //if rfbUpdateClient() finds out that it can't write to the socket,
+    //it closes it and sets it to -1. So, we just have to check this here
+    //and call rfbClientConnectionGone() if necessary. This will call
+    //the clientGoneHook which in turn will remove this RfbClient instance
+    //from the server manager and will call deleteLater() to delete it
+    if (d->client->sock == -1) {
+        kDebug() << "disconnected during update";
+        d->notifier->setEnabled(false);
+        rfbClientConnectionGone(d->client);
     }
+}
 
-    setOnHold(false);
-    setControlEnabled(dialog->cbAllowRemoteControl->isChecked());
-    setStatusConnected();
+//*************
+
+PendingRfbClient::PendingRfbClient(rfbClientPtr client, QObject *parent)
+    : QObject(parent), m_rfbClient(client)
+{
+    kDebug();
+    QMetaObject::invokeMethod(this, "processNewClient", Qt::QueuedConnection);
 }
 
-void RfbClient::dialogRejected()
+PendingRfbClient::~PendingRfbClient()
 {
+    kDebug();
+}
+
+void PendingRfbClient::accept(RfbClient *newClient)
+{
+    kDebug() << "accepted connection";
+
+    m_rfbClient->clientData = newClient;
+    newClient->setOnHold(false);
+
+    Q_EMIT finished(newClient);
+    deleteLater();
+}
+
+static void clientGoneHookNoop(rfbClientPtr cl) { Q_UNUSED(cl); }
+
+void PendingRfbClient::reject()
+{
     kDebug() << "refused connection";
-    closeConnection();
+
+    //override the clientGoneHook that was previously set by RfbServer
+    m_rfbClient->clientGoneHook = clientGoneHookNoop;
+    rfbCloseClient(m_rfbClient);
+    rfbClientConnectionGone(m_rfbClient);
+
+    Q_EMIT finished(NULL);
+    deleteLater();
 }
 
+
 #include "rfbclient.moc"
--- trunk/KDE/kdenetwork/krfb/krfb/rfbclient.h #1195291:1195292
@@ -27,6 +27,7 @@
 {
     Q_OBJECT
     Q_PROPERTY(bool controlEnabled READ controlEnabled WRITE setControlEnabled \
NOTIFY controlEnabledChanged) +    Q_PROPERTY(bool onHold READ isOnHold WRITE \
setOnHold NOTIFY holdStatusChanged)  public:
     RfbClient(rfbClientPtr client, QObject *parent = 0);
     virtual ~RfbClient();
@@ -38,28 +39,24 @@
     bool controlEnabled() const;
     void setControlEnabled(bool enabled);
 
+    bool isOnHold() const;
+
 public Q_SLOTS:
     void setOnHold(bool onHold);
     void closeConnection();
 
 Q_SIGNALS:
     void controlEnabledChanged(bool enabled);
-    void connected(RfbClient *self);
+    void holdStatusChanged(bool onHold);
 
 protected:
     friend class RfbServer;
     friend class RfbServerManager;
 
-    ///called by RfbServer to begin handling the client
-    virtual rfbNewClientAction doHandle();
-
     ///called by RfbServerManager to send framebuffer updates
     ///and check for possible disconnection
     void update();
 
-    bool isConnected() const;
-    void setStatusConnected(); ///call to declare the client as connected
-
     virtual void handleKeyboardEvent(bool down, rfbKeySym keySym);
     virtual void handleMouseEvent(int buttonMask, int x, int y);
 
@@ -79,12 +76,31 @@
 
 private Q_SLOTS:
     void onSocketActivated();
-    void dialogAccepted();
-    void dialogRejected();
 
 private:
     struct Private;
     Private *const d;
 };
 
+
+class PendingRfbClient : public QObject
+{
+    Q_OBJECT
+public:
+    PendingRfbClient(rfbClientPtr client, QObject *parent = 0);
+    virtual ~PendingRfbClient();
+
+Q_SIGNALS:
+    void finished(RfbClient *client);
+
+protected Q_SLOTS:
+    virtual void processNewClient() = 0;
+
+    void accept(RfbClient *newClient);
+    void reject();
+
+protected:
+    rfbClientPtr m_rfbClient;
+};
+
 #endif // RFBCLIENT_H
--- trunk/KDE/kdenetwork/krfb/krfb/rfbserver.cpp #1195291:1195292
@@ -203,20 +203,26 @@
     rfbProcessNewConnection(d->screen);
 }
 
+void RfbServer::pendingClientFinished(RfbClient *client)
+{
+    kDebug();
+    if (client) {
+        RfbServerManager::instance()->addClient(client);
+    }
+}
+
 //static
 rfbNewClientAction RfbServer::newClientHook(rfbClientPtr cl)
 {
     kDebug() << "New client";
     RfbServer *server = static_cast<RfbServer*>(cl->screen->screenData);
 
-    RfbClient *client = server->newClient(cl);
-    RfbServerManager::instance()->addClient(client);
+    PendingRfbClient *pendingClient = server->newClient(cl);
+    connect(pendingClient, SIGNAL(finished(RfbClient*)),
+            server, SLOT(pendingClientFinished(RfbClient*)));
 
-    //clientData is used by the static callbacks to determine their context
-    cl->clientData = client;
     cl->clientGoneHook = clientGoneHook;
-
-    return client->doHandle();
+    return RFB_CLIENT_ON_HOLD;
 }
 
 //static
--- trunk/KDE/kdenetwork/krfb/krfb/rfbserver.h #1195291:1195292
@@ -48,9 +48,10 @@
 
 private Q_SLOTS:
     void onListenSocketActivated();
+    void pendingClientFinished(RfbClient *client);
 
 protected:
-    virtual RfbClient *newClient(rfbClientPtr client) = 0;
+    virtual PendingRfbClient *newClient(rfbClientPtr client) = 0;
 
 private:
     static rfbNewClientAction newClientHook(rfbClientPtr cl);
--- trunk/KDE/kdenetwork/krfb/krfb/rfbservermanager.cpp #1195291:1195292
@@ -209,8 +209,7 @@
     }
     d->clients.insert(cc);
 
-    QObject::connect(cc, SIGNAL(connected(RfbClient*)),
-                     this, SIGNAL(clientConnected(RfbClient*)));
+    Q_EMIT clientConnected(cc);
 }
 
 void RfbServerManager::removeClient(RfbClient* cc)
@@ -222,9 +221,7 @@
         d->rfbUpdateTimer.stop();
     }
 
-    if (cc->isConnected()) {
         Q_EMIT clientDisconnected(cc);
     }
-}
 
 #include "rfbservermanager.moc"
--- trunk/KDE/kdenetwork/krfb/krfb/tubesrfbserver.cpp #1195291:1195292
@@ -17,6 +17,7 @@
     along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 #include "tubesrfbserver.h"
+#include "tubesrfbclient.h"
 #include "sockethelpers.h"
 
 #include <QtGui/QApplication>
@@ -61,72 +62,11 @@
 
 //**************
 
-class TubesRfbClient : public RfbClient
-{
-public:
-    TubesRfbClient(rfbClientPtr client, QObject* parent = 0);
-
-    virtual QString name() const;
-    void setContact(const Tp::ContactPtr & contact);
-
-protected:
-    virtual rfbNewClientAction doHandle();
-
-private:
-    Tp::ContactPtr m_contact;
-    bool m_doHandleCalled;
-};
-
-TubesRfbClient::TubesRfbClient(rfbClientPtr client, QObject* parent)
-    : RfbClient(client, parent), m_doHandleCalled(false)
-{
-}
-
-QString TubesRfbClient::name() const
-{
-    if (m_contact) {
-        return m_contact->alias();
-    } else {
-        return RfbClient::name();
-    }
-}
-
-void TubesRfbClient::setContact(const Tp::ContactPtr & contact)
-{
-    m_contact = contact;
-    if (m_doHandleCalled) {
-        //doHandle has already been called, so we need to call the parent's \
                implementation here
-        rfbNewClientAction action = RfbClient::doHandle();
-
-        //we were previously on hold, so we now need to act if
-        //the parent's doHandle() says we must do something else
-        if (action == RFB_CLIENT_ACCEPT) {
-            setOnHold(false);
-        } else if (action == RFB_CLIENT_REFUSE) {
-            closeConnection();
-        } //else if action == RFB_CLIENT_ON_HOLD there is nothing to do
-    }
-}
-
-rfbNewClientAction TubesRfbClient::doHandle()
-{
-    if (!m_contact) {
-        //no associated contact yet, hold.
-        m_doHandleCalled = true; //act when a contact is set
-        return RFB_CLIENT_ON_HOLD;
-    } else {
-        //we have a contact, begin handling
-        return RfbClient::doHandle();
-    }
-}
-
-//**************
-
 struct TubesRfbServer::Private
 {
     Tp::ChannelPtr channel;
     QHash<int, Tp::ContactPtr> contactsPerPort;
-    QHash<int, TubesRfbClient*> clientsPerPort;
+    QHash<int, PendingTubesRfbClient*> clientsPerPort;
 };
 
 TubesRfbServer::TubesRfbServer(const Tp::ChannelPtr & channel, QObject *parent)
@@ -153,11 +93,11 @@
     delete d;
 }
 
-RfbClient* TubesRfbServer::newClient(rfbClientPtr client)
+PendingRfbClient* TubesRfbServer::newClient(rfbClientPtr client)
 {
     kDebug() << "new tubes client";
 
-    TubesRfbClient *c = new TubesRfbClient(client, this);
+    PendingTubesRfbClient *c = new PendingTubesRfbClient(client, this);
     int port = peerPort(client->sock);
 
     d->clientsPerPort[port] = c;
--- trunk/KDE/kdenetwork/krfb/krfb/tubesrfbserver.h #1195291:1195292
@@ -29,7 +29,7 @@
     TubesRfbServer(const Tp::ChannelPtr & channel, QObject* parent = 0);
     virtual ~TubesRfbServer();
 
-    virtual RfbClient* newClient(rfbClientPtr client);
+    virtual PendingRfbClient* newClient(rfbClientPtr client);
 
 private Q_SLOTS:
     void close();


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic