[Libreoffice-commits] .: sd/Library_sd.mk sd/source

Andrzej J.R. Hunt ajrhunt at kemper.freedesktop.org
Fri Aug 10 08:21:37 PDT 2012


 sd/Library_sd.mk                            |    1 
 sd/source/ui/dlg/RemoteDialog.cxx           |    6 
 sd/source/ui/inc/RemoteServer.hxx           |   42 ++++--
 sd/source/ui/remotecontrol/Communicator.cxx |  128 ++++++++++++++++++++
 sd/source/ui/remotecontrol/Communicator.hxx |   62 ++++++++++
 sd/source/ui/remotecontrol/Listener.cxx     |   13 +-
 sd/source/ui/remotecontrol/Listener.hxx     |    6 
 sd/source/ui/remotecontrol/Server.cxx       |  173 +++++++++++-----------------
 8 files changed, 304 insertions(+), 127 deletions(-)

New commits:
commit 2a248dc15ff314a630b19536c32c6ce6fd4959d1
Author: Andrzej J.R. Hunt <andrzej at ahunt.org>
Date:   Fri Aug 10 17:20:16 2012 +0200

    Refactored remote communication to allow for pairing.
    
    Change-Id: Ia31e33fca6dca47faa1fad1a5879c3902df05835

diff --git a/sd/Library_sd.mk b/sd/Library_sd.mk
index 1fb99e0..92db929 100644
--- a/sd/Library_sd.mk
+++ b/sd/Library_sd.mk
@@ -327,6 +327,7 @@ $(eval $(call gb_Library_add_exception_objects,sd,\
     sd/source/ui/presenter/PresenterPreviewCache \
     sd/source/ui/presenter/PresenterTextView \
     sd/source/ui/presenter/SlideRenderer \
+    sd/source/ui/remotecontrol/Communicator \
     sd/source/ui/remotecontrol/DiscoveryService \
     sd/source/ui/remotecontrol/ImagePreparer \
     sd/source/ui/remotecontrol/Server \
diff --git a/sd/source/ui/dlg/RemoteDialog.cxx b/sd/source/ui/dlg/RemoteDialog.cxx
index 85d5ad2..465febc 100644
--- a/sd/source/ui/dlg/RemoteDialog.cxx
+++ b/sd/source/ui/dlg/RemoteDialog.cxx
@@ -26,12 +26,12 @@ RemoteDialog::RemoteDialog( Window *pWindow ) :
 {
      FreeResource();
 
-    vector<ClientInfo> aClients( RemoteServer::getClients() );
+    vector<ClientInfo*> aClients( RemoteServer::getClients() );
 
-    for ( vector<ClientInfo>::const_iterator aIt( aClients.begin() );
+    for ( vector<ClientInfo*>::const_iterator aIt( aClients.begin() );
         aIt < aClients.end(); aIt++ )
     {
-        mClientBox.addEntry( *aIt );
+        mClientBox.addEntry( **aIt );
     }
 
     mButtonConnect.SetClickHdl( LINK( this, RemoteDialog, HandleConnectButton ) );
diff --git a/sd/source/ui/inc/RemoteServer.hxx b/sd/source/ui/inc/RemoteServer.hxx
index d3e202b..a77f5ab 100644
--- a/sd/source/ui/inc/RemoteServer.hxx
+++ b/sd/source/ui/inc/RemoteServer.hxx
@@ -16,6 +16,7 @@
 #include <sys/types.h>
 #include <vector>
 
+#include <osl/mutex.hxx>
 #include <osl/socket.hxx>
 #include <rtl/ref.hxx>
 #include <salhelper/thread.hxx>
@@ -36,10 +37,7 @@ namespace css = ::com::sun::star;
 
 namespace sd
 {
-
-    class Transmitter;
-    class Listener;
-    class ImagePreparer;
+    class Communicator;
 
     struct ClientInfo
     {
@@ -47,33 +45,53 @@ namespace sd
         rtl::OUString mAddress;
 
         enum PROTOCOL { NETWORK = 1, BLUETOOTH };
-        ClientInfo( OUString rName, OUString rAddress) :
+        ClientInfo( const rtl::OUString rName, const rtl::OUString rAddress ) :
             mName( rName ),
             mAddress( rAddress ) {}
     };
 
+    struct ClientInfoInternal:
+        ClientInfo
+    {
+        osl::StreamSocket mStreamSocket;
+        rtl::OUString mPin;
+
+        ClientInfoInternal( const rtl::OUString rName,
+                            const rtl::OUString rAddress,
+                            osl::StreamSocket &rSocket, rtl::OUString rPin ):
+                ClientInfo( rName, rAddress ),
+                mStreamSocket( rSocket ),
+                mPin( rPin ) {}
+    };
+
     class RemoteServer : public salhelper::Thread
     {
         public:
+            // Internal setup
             static void setup();
+
+            // For slideshowimpl to inform us.
             static void presentationStarted( const css::uno::Reference<
                 css::presentation::XSlideShowController > &rController );
             static void presentationStopped();
-            void informListenerDestroyed();
 
-            SD_DLLPUBLIC static std::vector<ClientInfo> getClients();
+            // For the control dialog
+            SD_DLLPUBLIC static std::vector<ClientInfo*> getClients();
             SD_DLLPUBLIC static void connectClient( ClientInfo aClient, rtl::OString aPin );
+
+            // For the communicator
+            static void removeCommunicator( Communicator* pCommunicator );
         private:
             RemoteServer();
             ~RemoteServer();
             static RemoteServer *spServer;
             osl::AcceptorSocket mSocket;
-            osl::StreamSocket mStreamSocket;
-            void pairClient();
-            void listenThread();
+
+            ::osl::Mutex mDataMutex;
+            ::std::vector<Communicator*> mCommunicators;
+            ::std::vector<ClientInfoInternal*> mAvailableClients;
+
             void execute();
-            static Transmitter *pTransmitter;
-            static rtl::Reference<Listener> mListener;
     };
 }
 
diff --git a/sd/source/ui/remotecontrol/Communicator.cxx b/sd/source/ui/remotecontrol/Communicator.cxx
new file mode 100644
index 0000000..d4775f9
--- /dev/null
+++ b/sd/source/ui/remotecontrol/Communicator.cxx
@@ -0,0 +1,128 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+#include <algorithm>
+#include <vector>
+
+#include <comphelper/processfactory.hxx>
+
+#include "Communicator.hxx"
+#include "ImagePreparer.hxx"
+#include "Listener.hxx"
+#include "Receiver.hxx"
+#include "RemoteServer.hxx"
+
+using namespace sd;
+using namespace std;
+using namespace com::sun::star;
+using namespace osl;
+
+Communicator::Communicator( StreamSocket &aSocket ):
+    Thread( "CommunicatorThread" ),
+    mSocket( aSocket ),
+    pTransmitter( 0 ),
+    mListener( 0 )
+{
+}
+
+Communicator::~Communicator()
+{
+}
+
+// Run as a thread
+void Communicator::execute()
+{
+    pTransmitter = new Transmitter( mSocket );
+    pTransmitter->launch();
+    Receiver aReceiver( pTransmitter );
+    try {
+        uno::Reference< lang::XMultiServiceFactory > xServiceManager(
+            ::comphelper::getProcessServiceFactory(), uno::UNO_QUERY_THROW );
+        uno::Reference< frame::XFramesSupplier > xFramesSupplier( xServiceManager->createInstance(
+        "com.sun.star.frame.Desktop" ) , uno::UNO_QUERY_THROW );
+        uno::Reference< frame::XFrame > xFrame ( xFramesSupplier->getActiveFrame(), uno::UNO_QUERY_THROW );
+        uno::Reference<presentation::XPresentationSupplier> xPS ( xFrame->getController()->getModel(), uno::UNO_QUERY_THROW);
+        uno::Reference<presentation::XPresentation2> xPresentation(
+            xPS->getPresentation(), uno::UNO_QUERY_THROW);
+        if ( xPresentation->isRunning() )
+        {
+            presentationStarted( xPresentation->getController() );
+        }
+    }
+    catch (uno::RuntimeException &)
+    {
+    }
+
+    sal_uInt64 aRet, aRead;
+    vector<char> aBuffer;
+    vector<OString> aCommand;
+    aRead = 0;
+    while ( true )
+    {
+        aBuffer.resize( aRead + 100 );
+        aRet = mSocket.recv( &aBuffer[aRead], 100 );
+        if ( aRet == 0 )
+        {
+            break; // I.e. transmission finished.
+        }
+        aRead += aRet;
+        vector<char>::iterator aIt;
+        while ( (aIt = find( aBuffer.begin(), aBuffer.end(), '\n' ))
+            != aBuffer.end() )
+        {
+            sal_uInt64 aLocation = aIt - aBuffer.begin();
+
+            aCommand.push_back( OString( &(*aBuffer.begin()), aLocation ) );
+            if ( aIt == aBuffer.begin() )
+            {
+                aReceiver.parseCommand( aCommand );
+                aCommand.clear();
+            }
+            aBuffer.erase( aBuffer.begin(), aIt + 1 ); // Also delete the empty line
+            aRead -= (aLocation + 1);
+        }
+    }
+    // TODO: deal with transmision errors gracefully.
+    disposeListener();
+
+    pTransmitter->notifyFinished();
+    pTransmitter->join();
+    pTransmitter = NULL;
+
+    RemoteServer::removeCommunicator( this );
+}
+
+void Communicator::informListenerDestroyed()
+{
+    mListener.clear();
+}
+
+void Communicator::presentationStarted( const css::uno::Reference<
+     css::presentation::XSlideShowController > &rController )
+{
+    if ( pTransmitter )
+    {
+        mListener = rtl::Reference<Listener>( new Listener( this, pTransmitter ) );
+        mListener->init( rController );
+    }
+}
+
+void Communicator::disposeListener()
+{
+    if ( mListener.is() )
+    {
+        mListener->disposing();
+        mListener = NULL;
+    }
+}
+
+Transmitter* Communicator::getTransmitter()
+{
+    return pTransmitter;
+}
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sd/source/ui/remotecontrol/Communicator.hxx b/sd/source/ui/remotecontrol/Communicator.hxx
new file mode 100644
index 0000000..089fffa
--- /dev/null
+++ b/sd/source/ui/remotecontrol/Communicator.hxx
@@ -0,0 +1,62 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+#ifndef _SD_IMPRESSREMOTE_COMMUNICATOR_HXX
+#define _SD_IMPRESSREMOTE_COMMUNICATOR_HXX
+
+// SERVER
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <vector>
+
+#include <osl/socket.hxx>
+#include <rtl/ref.hxx>
+#include <salhelper/thread.hxx>
+
+#include <com/sun/star/presentation/XSlideShowController.hpp>
+
+#define CHARSET RTL_TEXTENCODING_UTF8
+namespace css = ::com::sun::star;
+
+namespace sd
+{
+
+    class Transmitter;
+    class Listener;
+    class ImagePreparer;
+
+    /** Class used for communication with one single client, dealing with all
+     * tasks specific to this client.
+     *
+     * Needs to be created, then started using launch(), disposes itself.
+     */
+    class Communicator : public salhelper::Thread
+    {
+        public:
+            Communicator( osl::StreamSocket &aSocket );
+            ~Communicator();
+
+            Transmitter* getTransmitter();
+            void presentationStarted( const css::uno::Reference<
+                css::presentation::XSlideShowController > &rController );
+            void informListenerDestroyed();
+            void disposeListener();
+
+        private:
+            void execute();
+            osl::StreamSocket mSocket;
+
+            Transmitter *pTransmitter;
+            rtl::Reference<Listener> mListener;
+    };
+}
+
+#endif // _SD_IMPRESSREMOTE_COMMUNICATOR_HXX
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sd/source/ui/remotecontrol/Listener.cxx b/sd/source/ui/remotecontrol/Listener.cxx
index e326ea5..5044169 100644
--- a/sd/source/ui/remotecontrol/Listener.cxx
+++ b/sd/source/ui/remotecontrol/Listener.cxx
@@ -22,9 +22,10 @@ using rtl::OString;
 using rtl::OStringBuffer;
 
 
-Listener::Listener( const ::rtl::Reference<RemoteServer>& rServer, sd::Transmitter *aTransmitter  )
-    : ::cppu::WeakComponentImplHelper1< XSlideShowListener >( m_aMutex ),
-      mServer( rServer ),
+Listener::Listener( const ::rtl::Reference<Communicator>& rCommunicator,
+                    sd::Transmitter *aTransmitter  ):
+      ::cppu::WeakComponentImplHelper1< XSlideShowListener >( m_aMutex ),
+      mCommunicator( rCommunicator ),
       pTransmitter( NULL ),
       mPreparer()
 {
@@ -43,11 +44,11 @@ void Listener::init( const css::uno::Reference< css::presentation::XSlideShowCon
         aController->addSlideShowListener( this );
 
         sal_Int32 aSlides = aController->getSlideCount();
-	sal_Int32 aCurrentSlide = aController->getCurrentSlideIndex();
+        sal_Int32 aCurrentSlide = aController->getCurrentSlideIndex();
         OStringBuffer aBuffer;
         aBuffer.append( "slideshow_started\n" )
                .append( OString::valueOf( aSlides ) ).append("\n")
-	       .append( OString::valueOf( aCurrentSlide ) ).append( "\n\n" );
+        .append( OString::valueOf( aCurrentSlide ) ).append( "\n\n" );
 
         pTransmitter->addMessage( aBuffer.makeStringAndClear(),
                                   Transmitter::PRIORITY_HIGH );
@@ -146,7 +147,7 @@ void SAL_CALL Listener::disposing (void)
         mController->removeSlideShowListener( this );
         mController = NULL;
     }
-    mServer->informListenerDestroyed();
+    mCommunicator->informListenerDestroyed();
 }
 
 void SAL_CALL Listener::disposing (
diff --git a/sd/source/ui/remotecontrol/Listener.hxx b/sd/source/ui/remotecontrol/Listener.hxx
index 1a1226d..3eb7f10 100644
--- a/sd/source/ui/remotecontrol/Listener.hxx
+++ b/sd/source/ui/remotecontrol/Listener.hxx
@@ -19,7 +19,7 @@
 #include <osl/socket.hxx>
 #include <rtl/ref.hxx>
 
-#include "RemoteServer.hxx"
+#include "Communicator.hxx"
 #include "Transmitter.hxx"
 #include "ImagePreparer.hxx"
 
@@ -35,7 +35,7 @@ class Listener
       public ::cppu::WeakComponentImplHelper1< css::presentation::XSlideShowListener >
 {
 public:
-    Listener( const ::rtl::Reference<RemoteServer>& rServer, sd::Transmitter *aTransmitter );
+    Listener( const ::rtl::Reference<Communicator>& rServer, sd::Transmitter *aTransmitter );
     ~Listener();
     void init( const css::uno::Reference< css::presentation::XSlideShowController >& aController );
 
@@ -65,7 +65,7 @@ public:
     throw (com::sun::star::uno::RuntimeException);
 
 private:
-    rtl::Reference<RemoteServer> mServer;
+    rtl::Reference<Communicator> mCommunicator;
     sd::Transmitter *pTransmitter;
     css::uno::Reference< css::presentation::XSlideShowController > mController;
     rtl::Reference<sd::ImagePreparer> mPreparer;
diff --git a/sd/source/ui/remotecontrol/Server.cxx b/sd/source/ui/remotecontrol/Server.cxx
index 61284ff..eb4adc1 100644
--- a/sd/source/ui/remotecontrol/Server.cxx
+++ b/sd/source/ui/remotecontrol/Server.cxx
@@ -25,9 +25,27 @@ using namespace std;
 using namespace sd;
 using namespace ::com::sun::star;
 using rtl::OString;
-
-RemoteServer::RemoteServer()
-:  Thread( "RemoteServerThread" ), mSocket()
+using namespace ::osl;
+
+// struct ClientInfoInternal:
+//     ClientInfo
+// {
+//     osl::StreamSocket mStreamSocket;
+//     rtl::OUString mPin;
+//     ClientInfoInternal( const rtl::OUString rName,
+//                         const rtl::OUString rAddress,
+//                         osl::StreamSocket &rSocket, rtl::OUString rPin ):
+//             ClientInfo( rName, rAddress ),
+//             mStreamSocket( rSocket ),
+//             mPin( rPin ) {}
+// };
+
+RemoteServer::RemoteServer() :
+    Thread( "RemoteServerThread" ),
+    mSocket(),
+    mDataMutex(),
+    mCommunicators(),
+    mAvailableClients()
 {
 }
 
@@ -35,75 +53,6 @@ RemoteServer::~RemoteServer()
 {
 }
 
-// Run as a thread
-void RemoteServer::listenThread()
-{
-    pTransmitter = new Transmitter( mStreamSocket );
-    pTransmitter->launch();
-    Receiver aReceiver( pTransmitter );
-    try {
-        uno::Reference< lang::XMultiServiceFactory > xServiceManager(
-            ::comphelper::getProcessServiceFactory(), uno::UNO_QUERY_THROW );
-        uno::Reference< frame::XFramesSupplier > xFramesSupplier( xServiceManager->createInstance(
-        "com.sun.star.frame.Desktop" ) , uno::UNO_QUERY_THROW );
-        uno::Reference< frame::XFrame > xFrame ( xFramesSupplier->getActiveFrame(), uno::UNO_QUERY_THROW );
-        uno::Reference<presentation::XPresentationSupplier> xPS ( xFrame->getController()->getModel(), uno::UNO_QUERY_THROW);
-        uno::Reference<presentation::XPresentation2> xPresentation(
-            xPS->getPresentation(), uno::UNO_QUERY_THROW);
-        if ( xPresentation->isRunning() )
-        {
-            presentationStarted( xPresentation->getController() );
-        }
-    }
-    catch (uno::RuntimeException &)
-    {
-    }
-
-    sal_uInt64 aRet, aRead;
-    vector<char> aBuffer;
-    vector<OString> aCommand;
-    aRead = 0;
-    while ( true )
-    {
-        aBuffer.resize( aRead + 100 );
-        aRet = mStreamSocket.recv( &aBuffer[aRead], 100 );
-        if ( aRet == 0 )
-        {
-            break; // I.e. transmission finished.
-        }
-        aRead += aRet;
-        vector<char>::iterator aIt;
-        while ( (aIt = find( aBuffer.begin(), aBuffer.end(), '\n' ))
-            != aBuffer.end() )
-        {
-            sal_uInt64 aLocation = aIt - aBuffer.begin();
-
-            aCommand.push_back( OString( &(*aBuffer.begin()), aLocation ) );
-            if ( aIt == aBuffer.begin() )
-            {
-                aReceiver.parseCommand( aCommand );
-                aCommand.clear();
-            }
-            aBuffer.erase( aBuffer.begin(), aIt + 1 ); // Also delete the empty line
-            aRead -= (aLocation + 1);
-        }
-    }
-    // TODO: deal with transmision errors gracefully.
-    presentationStopped();
-
-    pTransmitter->notifyFinished();
-    pTransmitter->join();
-    pTransmitter = NULL;
-    fprintf( stderr, "Finished listening\n" );
-}
-
-void RemoteServer::pairClient()
-{
-    // Pairing: client sends PIN, server asks user, replies with accepted/rejected.
-    // We have to wait here until the user opens the dialog via the menu,
-    // typs in the pin etc.
-}
-
 void RemoteServer::execute()
 {
     osl::SocketAddr aAddr( "0", PORT );
@@ -118,60 +67,78 @@ void RemoteServer::execute()
     }
     while ( true )
     {
-        fprintf( stderr, "Awaiting a connection.\n" );
-        if ( mSocket.acceptConnection( mStreamSocket ) == osl_Socket_Error ) {
-            // Socket closed or other problem
-            return;
+        StreamSocket aSocket;
+        if ( mSocket.acceptConnection( aSocket ) == osl_Socket_Error ) {
+            MutexGuard aGuard( mDataMutex );
+            // FIXME: read one line in, parse the data.
+            mAvailableClients.push_back( new ClientInfoInternal( "A name",
+                                        "An address", aSocket, "0000" ) );
         }
-        fprintf( stderr, "Accepted a connection!\n" );
-        listenThread();
     }
 
 }
 
-void RemoteServer::informListenerDestroyed()
+RemoteServer *sd::RemoteServer::spServer = NULL;
+
+void RemoteServer::setup()
 {
-    mListener.clear();
+    if (spServer)
+        return;
+
+    spServer = new RemoteServer();
+    spServer->launch();
 }
 
+
 void RemoteServer::presentationStarted( const css::uno::Reference<
-     css::presentation::XSlideShowController > &rController )
+                css::presentation::XSlideShowController > &rController )
 {
-    if ( pTransmitter )
+    if ( !spServer )
+        return;
+    MutexGuard aGuard( spServer->mDataMutex );
+    for ( vector<Communicator*>::const_iterator aIt = spServer->mCommunicators.begin();
+         aIt < spServer->mCommunicators.end(); aIt++ )
     {
-        mListener = rtl::Reference<Listener>( new Listener( spServer, pTransmitter ) );
-        mListener->init( rController );
+        (*aIt)->presentationStarted( rController );
     }
 }
-
 void RemoteServer::presentationStopped()
 {
-    if ( mListener.is() )
+    if ( !spServer )
+        return;
+    MutexGuard aGuard( spServer->mDataMutex );
+    for ( vector<Communicator*>::const_iterator aIt = spServer->mCommunicators.begin();
+         aIt < spServer->mCommunicators.end(); aIt++ )
     {
-        mListener->disposing();
-        mListener = NULL;
+        (*aIt)->disposeListener();
     }
 }
 
-RemoteServer *sd::RemoteServer::spServer = NULL;
-Transmitter *sd::RemoteServer::pTransmitter = NULL;
-rtl::Reference<Listener> sd::RemoteServer::mListener = NULL;
-
-void RemoteServer::setup()
+void RemoteServer::removeCommunicator( Communicator* mCommunicator )
 {
-  if (spServer)
-    return;
-
-  spServer = new RemoteServer();
-  spServer->launch();
+    if ( !spServer )
+        return;
+    MutexGuard aGuard( spServer->mDataMutex );
+    for ( vector<Communicator*>::iterator aIt = spServer->mCommunicators.begin();
+         aIt < spServer->mCommunicators.end(); aIt++ )
+    {
+        if ( mCommunicator == *aIt )
+        {
+            spServer->mCommunicators.erase( aIt );
+            break;
+        }
+    }
 }
 
-std::vector<ClientInfo> RemoteServer::getClients()
+std::vector<ClientInfo*> RemoteServer::getClients()
 {
-    std::vector<ClientInfo> aV;
-    aV.push_back( ClientInfo( "A phone", "akaakaskj" ) );
-    aV.push_back( ClientInfo( "B phone", "iiiiiii" ) );
-    return aV;
+    if ( !spServer )
+        std::vector<ClientInfo*>();
+    MutexGuard aGuard( spServer->mDataMutex );
+    std::vector<ClientInfo*> aClients;
+    aClients.assign( spServer->mAvailableClients.begin(),
+                     spServer->mAvailableClients.end() );
+    return aClients;
 }
 
 void RemoteServer::connectClient( ClientInfo aClient, rtl::OString aPin )


More information about the Libreoffice-commits mailing list