Kaydet (Commit) 2a248dc1 authored tarafından Andrzej J.R. Hunt's avatar Andrzej J.R. Hunt

Refactored remote communication to allow for pairing.

Change-Id: Ia31e33fca6dca47faa1fad1a5879c3902df05835
üst 0c0d2458
......@@ -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 \
......
......@@ -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 ) );
......
......@@ -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;
};
}
......
/* -*- 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: */
/* -*- 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: */
......@@ -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 (
......
......@@ -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;
......
......@@ -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 )
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment