2006-08-04 08:56:09 +00:00
|
|
|
/*************************************************************************
|
|
|
|
*
|
|
|
|
* OpenOffice.org - a multi-platform office productivity suite
|
|
|
|
*
|
|
|
|
* $RCSfile: updatecheck.cxx,v $
|
|
|
|
*
|
2006-09-16 12:30:50 +00:00
|
|
|
* $Revision: 1.4 $
|
2006-08-04 08:56:09 +00:00
|
|
|
*
|
2006-09-16 12:30:50 +00:00
|
|
|
* last change: $Author: obo $ $Date: 2006-09-16 13:30:09 $
|
2006-08-04 08:56:09 +00:00
|
|
|
*
|
|
|
|
* The Contents of this file are made available subject to
|
|
|
|
* the terms of GNU Lesser General Public License Version 2.1.
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* GNU Lesser General Public License Version 2.1
|
|
|
|
* =============================================
|
|
|
|
* Copyright 2005 by Sun Microsystems, Inc.
|
|
|
|
* 901 San Antonio Road, Palo Alto, CA 94303, USA
|
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License version 2.1, as published by the Free Software Foundation.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Lesser General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
* License along with this library; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
|
|
|
|
* MA 02111-1307 USA
|
|
|
|
*
|
|
|
|
************************************************************************/
|
|
|
|
|
2006-09-16 12:30:50 +00:00
|
|
|
// MARKER(update_precomp.py): autogen include statement, do not remove
|
|
|
|
#include "precompiled_extensions.hxx"
|
|
|
|
|
2006-08-04 08:56:09 +00:00
|
|
|
#include <cppuhelper/implbase3.hxx>
|
|
|
|
#include <cppuhelper/implementationentry.hxx>
|
|
|
|
|
|
|
|
#ifndef _COM_SUN_STAR_LANG_XCOMPONENT_HPP_
|
|
|
|
#include <com/sun/star/lang/XComponent.hpp>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// #ifndef _COM_SUN_STAR_BEANS_XPROPERTYSTATE_HPP_
|
|
|
|
// #include <com/sun/star/beans/XPropertyState.hpp>
|
|
|
|
// #endif
|
|
|
|
|
|
|
|
#ifndef _COM_SUN_STAR_BEANS_PROPERTYVALUE_HPP_
|
|
|
|
#include <com/sun/star/beans/PropertyValue.hpp>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef _COM_SUN_STAR_FRAME_XFRAME_HPP_
|
|
|
|
#include <com/sun/star/frame/XFrame.hpp>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef _COM_SUN_STAR_FRAME_DISPATCHRESULTEVENT_HPP_
|
|
|
|
#include <com/sun/star/frame/DispatchResultEvent.hpp>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef _COM_SUN_STAR_FRAME_DISPATCHRESULTSTATE_HPP_
|
|
|
|
#include <com/sun/star/frame/DispatchResultState.hpp>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef _COM_SUN_STAR_SYSTEM_XSYSTEMSHELLEXECUTE_HPP_
|
|
|
|
#include <com/sun/star/system/XSystemShellExecute.hpp>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef _COM_SUN_STAR_SYSTEM_SYSTEMSHELLEXECUTEFLAGS_HPP_
|
|
|
|
#include <com/sun/star/system/SystemShellExecuteFlags.hpp>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef _COM_SUN_STAR_TASK_XJOB_HPP_
|
|
|
|
#include <com/sun/star/task/XJob.hpp>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef _RTL_USTRBUF_HXX_
|
|
|
|
#include <rtl/ustrbuf.hxx>
|
|
|
|
#endif // _RTL_USTRBUF_HXX_
|
|
|
|
|
|
|
|
#include <rtl/bootstrap.hxx>
|
|
|
|
#include <osl/thread.h>
|
|
|
|
#include <osl/conditn.h>
|
|
|
|
#include <osl/process.h>
|
|
|
|
#include <osl/module.h>
|
|
|
|
|
|
|
|
#include "updateprotocol.hxx"
|
|
|
|
#include "updatecheckconfig.hxx"
|
|
|
|
|
|
|
|
namespace awt = com::sun::star::awt ;
|
|
|
|
namespace beans = com::sun::star::beans ;
|
|
|
|
namespace container = com::sun::star::container ;
|
|
|
|
namespace frame = com::sun::star::frame ;
|
|
|
|
namespace lang = com::sun::star::lang ;
|
|
|
|
namespace c3s = com::sun::star::system ;
|
|
|
|
namespace task = com::sun::star::task ;
|
|
|
|
namespace util = com::sun::star::util ;
|
|
|
|
namespace uno = com::sun::star::uno ;
|
|
|
|
|
|
|
|
extern "C" void SAL_CALL myThreadFunc(void*);
|
|
|
|
|
|
|
|
#define UNISTRING(s) rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(s))
|
|
|
|
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
T getValue( const uno::Sequence< beans::NamedValue >& rNamedValues, const sal_Char * pszName )
|
|
|
|
throw (uno::RuntimeException)
|
|
|
|
{
|
|
|
|
for( sal_Int32 n=0; n < rNamedValues.getLength(); n++ )
|
|
|
|
if( rNamedValues[n].Name.equalsAscii( pszName ) )
|
|
|
|
return rNamedValues[n].Value.get<T>();
|
|
|
|
|
|
|
|
return T();
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
template <typename T>
|
|
|
|
void setValue( uno::Sequence< beans::NamedValue >& rNamedValues, const sal_Char * pszName, T const & value )
|
|
|
|
throw (uno::RuntimeException)
|
|
|
|
{
|
|
|
|
for( sal_Int32 n=0; n < rNamedValues.getLength(); n++ )
|
|
|
|
if( rNamedValues[n].Name.equalsAscii( pszName ) )
|
|
|
|
rNamedValues[n].Value = uno::makeAny( value );
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
namespace
|
|
|
|
{
|
|
|
|
|
|
|
|
class UpdateCheckJob : public ::cppu::WeakImplHelper3< task::XJob, lang::XServiceInfo, lang::XEventListener >
|
|
|
|
{
|
|
|
|
uno::Reference<uno::XComponentContext> m_xContext;
|
|
|
|
|
|
|
|
uno::Reference<lang::XMultiServiceFactory> getConfigProvider() const;
|
|
|
|
|
|
|
|
uno::Reference< uno::XInterface > getConfigAccess(
|
|
|
|
rtl::OUString const & rNodePath,
|
|
|
|
rtl::OUString const & rService,
|
|
|
|
uno::Reference< lang::XMultiServiceFactory > const & rConfigProvider ) const;
|
|
|
|
|
|
|
|
inline uno::Reference< container::XNameAccess > getNameAccess(
|
|
|
|
rtl::OUString const & rNodePath,
|
|
|
|
uno::Reference< lang::XMultiServiceFactory > const & rConfigProvider ) const;
|
|
|
|
|
|
|
|
inline uno::Reference< container::XNameReplace > getUpdateAccess(
|
|
|
|
rtl::OUString const & rNodePath,
|
|
|
|
uno::Reference< lang::XMultiServiceFactory > const & rConfigProvider ) const;
|
|
|
|
|
|
|
|
inline uno::Reference< container::XNameAccess > getNameAccess(rtl::OUString const & rNodePath) const
|
|
|
|
{ return getNameAccess(rNodePath, getConfigProvider()); };
|
|
|
|
inline uno::Reference< container::XNameReplace > getUpdateAccess(rtl::OUString const & rNodePath) const
|
|
|
|
{ return getUpdateAccess(rNodePath, getConfigProvider()); };
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
uno::Reference<uno::XInterface> getUIService(sal_Bool bShowBubble) const;
|
|
|
|
uno::Reference<task::XInteractionHandler> getInteractionHandler() const;
|
|
|
|
uno::Reference<c3s::XSystemShellExecute> getShellExecuter() const;
|
|
|
|
|
|
|
|
static uno::Reference< uno::XInterface > g_aInstance;
|
|
|
|
|
|
|
|
// Not using the C++ wrappers because we need those in the global instance only
|
|
|
|
oslThread m_hThread;
|
|
|
|
oslModule m_hModule;
|
|
|
|
oslCondition m_hCondition;
|
|
|
|
|
|
|
|
void makeGlobal(const uno::Sequence<beans::NamedValue>& rNamedValues)
|
|
|
|
throw (uno::RuntimeException);
|
|
|
|
|
|
|
|
rtl::OUString m_aBuildId;
|
|
|
|
rtl::OUString getBuildId();
|
|
|
|
|
|
|
|
uno::Reference< uno::XInterface > m_xUIService;
|
|
|
|
|
|
|
|
rtl::OUString m_aBubbleHeading;
|
|
|
|
rtl::OUString m_aBubbleText;
|
|
|
|
|
|
|
|
sal_Bool (* m_pHasInternetConnection) ();
|
|
|
|
|
|
|
|
protected:
|
|
|
|
void runAsThread();
|
|
|
|
friend void SAL_CALL ::myThreadFunc(void *);
|
|
|
|
|
|
|
|
inline rtl::OUString getProductName() const;
|
2006-09-13 10:26:00 +00:00
|
|
|
inline rtl::OUString getLocale() const;
|
2006-08-04 08:56:09 +00:00
|
|
|
|
|
|
|
/* Used to avoid dialup login windows (on platforms we know how to double this) */
|
|
|
|
inline bool hasInternetConnection() const
|
|
|
|
{
|
|
|
|
if(m_pHasInternetConnection != NULL )
|
|
|
|
return (sal_True == m_pHasInternetConnection());
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
public:
|
|
|
|
UpdateCheckJob(const uno::Reference<uno::XComponentContext>&);
|
|
|
|
virtual ~UpdateCheckJob();
|
|
|
|
|
|
|
|
static uno::Sequence< rtl::OUString > getServiceNames();
|
|
|
|
static rtl::OUString getImplName();
|
|
|
|
|
|
|
|
// Allows runtime exceptions to be thrown by const methods
|
|
|
|
inline SAL_CALL operator uno::Reference< uno::XInterface > () const
|
|
|
|
{ return const_cast< cppu::OWeakObject * > (static_cast< cppu::OWeakObject const * > (this)); };
|
|
|
|
|
|
|
|
// XJob
|
|
|
|
virtual uno::Any SAL_CALL execute(const uno::Sequence<beans::NamedValue>&)
|
|
|
|
throw (lang::IllegalArgumentException, uno::Exception);
|
|
|
|
|
|
|
|
// XServiceInfo
|
|
|
|
virtual rtl::OUString SAL_CALL getImplementationName()
|
|
|
|
throw (uno::RuntimeException);
|
|
|
|
virtual sal_Bool SAL_CALL supportsService(rtl::OUString const & serviceName)
|
|
|
|
throw (uno::RuntimeException);
|
|
|
|
virtual uno::Sequence< rtl::OUString > SAL_CALL getSupportedServiceNames()
|
|
|
|
throw (uno::RuntimeException);
|
|
|
|
|
|
|
|
virtual void SAL_CALL disposing(const lang::EventObject&)
|
|
|
|
throw (uno::RuntimeException);
|
|
|
|
};
|
|
|
|
|
|
|
|
uno::Reference< uno::XInterface > UpdateCheckJob::g_aInstance;
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
UpdateCheckJob::UpdateCheckJob(const uno::Reference<uno::XComponentContext>& xContext) :
|
|
|
|
m_xContext(xContext),
|
|
|
|
m_pHasInternetConnection(NULL)
|
|
|
|
{
|
|
|
|
m_hThread = 0;
|
|
|
|
m_hModule = 0;
|
|
|
|
m_hCondition = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
UpdateCheckJob::~UpdateCheckJob()
|
|
|
|
{
|
|
|
|
if( m_hThread )
|
|
|
|
{
|
|
|
|
osl_terminateThread(m_hThread);
|
|
|
|
osl_setCondition(m_hCondition);
|
|
|
|
|
|
|
|
osl_joinWithThread(m_hThread);
|
|
|
|
osl_destroyThread(m_hThread);
|
|
|
|
}
|
|
|
|
|
|
|
|
if( m_hCondition )
|
|
|
|
osl_destroyCondition(m_hCondition);
|
|
|
|
|
|
|
|
if( m_hModule )
|
|
|
|
osl_unloadModule(m_hModule);
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
uno::Sequence< rtl::OUString >
|
|
|
|
UpdateCheckJob::getServiceNames()
|
|
|
|
{
|
|
|
|
uno::Sequence< rtl::OUString > aServiceList(1);
|
|
|
|
aServiceList[0] = UNISTRING( "com.sun.star.setup.UpdateCheck");
|
|
|
|
return aServiceList;
|
|
|
|
};
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
rtl::OUString
|
|
|
|
UpdateCheckJob::getImplName()
|
|
|
|
{
|
|
|
|
return UNISTRING( "vnd.sun.UpdateCheck");
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
uno::Reference< lang::XMultiServiceFactory >
|
|
|
|
UpdateCheckJob::getConfigProvider() const
|
|
|
|
{
|
|
|
|
uno::Reference<uno::XComponentContext> xContext(m_xContext);
|
|
|
|
|
|
|
|
if( !xContext.is() )
|
|
|
|
throw uno::RuntimeException(
|
|
|
|
UNISTRING( "UpdateCheckJob: empty component context" ), *this );
|
|
|
|
|
|
|
|
uno::Reference< lang::XMultiComponentFactory > xServiceManager(xContext->getServiceManager());
|
|
|
|
|
|
|
|
if( !xServiceManager.is() )
|
|
|
|
throw uno::RuntimeException(
|
|
|
|
UNISTRING( "UpdateCheckJob: unable to obtain service manager from component context" ), *this );
|
|
|
|
|
|
|
|
uno::Reference< lang::XMultiServiceFactory > xConfigurationProvider(
|
|
|
|
xServiceManager->createInstanceWithContext( UNISTRING( "com.sun.star.configuration.ConfigurationProvider" ), xContext ),
|
|
|
|
uno::UNO_QUERY_THROW);
|
|
|
|
|
|
|
|
return xConfigurationProvider;
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
uno::Reference< uno::XInterface >
|
|
|
|
UpdateCheckJob::getConfigAccess(
|
|
|
|
const rtl::OUString& rNodePath,
|
|
|
|
const rtl::OUString& rService,
|
|
|
|
uno::Reference< lang::XMultiServiceFactory > const & rxConfigProvider) const
|
|
|
|
{
|
|
|
|
beans::PropertyValue aProperty;
|
|
|
|
aProperty.Name = UNISTRING( "nodepath" );
|
|
|
|
aProperty.Value = uno::makeAny( rNodePath );
|
|
|
|
|
|
|
|
uno::Sequence< uno::Any > aArgumentList( 1 );
|
|
|
|
aArgumentList[0] = uno::makeAny( aProperty );
|
|
|
|
|
|
|
|
return rxConfigProvider->createInstanceWithArguments( rService, aArgumentList );
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
inline uno::Reference< container::XNameAccess >
|
|
|
|
UpdateCheckJob::getNameAccess(
|
|
|
|
rtl::OUString const & rNodePath,
|
|
|
|
uno::Reference< lang::XMultiServiceFactory > const & rxConfigProvider) const
|
|
|
|
{
|
|
|
|
return uno::Reference< container::XNameAccess > (
|
|
|
|
getConfigAccess( rNodePath,
|
|
|
|
UNISTRING("com.sun.star.configuration.ConfigurationAccess"),
|
|
|
|
rxConfigProvider ),
|
|
|
|
uno::UNO_QUERY_THROW );
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
inline uno::Reference< container::XNameReplace >
|
|
|
|
UpdateCheckJob::getUpdateAccess(
|
|
|
|
rtl::OUString const & rNodePath,
|
|
|
|
uno::Reference< lang::XMultiServiceFactory > const & rxConfigProvider) const
|
|
|
|
{
|
|
|
|
return uno::Reference< container::XNameReplace > (
|
|
|
|
getConfigAccess( rNodePath,
|
|
|
|
UNISTRING("com.sun.star.configuration.ConfigurationUpdateAccess"),
|
|
|
|
rxConfigProvider ),
|
|
|
|
uno::UNO_QUERY_THROW );
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
uno::Reference< uno::XInterface >
|
|
|
|
UpdateCheckJob::getUIService(sal_Bool bShowBubble) const
|
|
|
|
{
|
|
|
|
uno::Reference<uno::XComponentContext> xContext(m_xContext);
|
|
|
|
|
|
|
|
if( !xContext.is() )
|
|
|
|
throw uno::RuntimeException(
|
|
|
|
UNISTRING( "UpdateCheckJob: empty component context" ), *this );
|
|
|
|
|
|
|
|
uno::Reference< lang::XMultiComponentFactory > xServiceManager(xContext->getServiceManager());
|
|
|
|
|
|
|
|
if( !xServiceManager.is() )
|
|
|
|
throw uno::RuntimeException(
|
|
|
|
UNISTRING( "UpdateCheckJob: unable to obtain service manager from component context" ), *this );
|
|
|
|
|
|
|
|
rtl::OUString aPlaceholder( RTL_CONSTASCII_USTRINGPARAM("%PRODUCTNAME") );
|
|
|
|
rtl::OUString aProductName = getProductName();
|
|
|
|
|
|
|
|
uno::Sequence< uno::Any > aArgumentList(4);
|
|
|
|
// FIXME this should be another object ..
|
|
|
|
aArgumentList[0] = uno::makeAny( uno::Reference< task::XJob >(const_cast <UpdateCheckJob *> (this) ) );
|
|
|
|
aArgumentList[1] = uno::makeAny(
|
|
|
|
m_aBubbleHeading.replaceAt( m_aBubbleHeading.indexOf( aPlaceholder ),
|
|
|
|
aPlaceholder.getLength(), aProductName) );
|
|
|
|
aArgumentList[2] = uno::makeAny( m_aBubbleText );
|
|
|
|
aArgumentList[3] = uno::makeAny( bShowBubble );
|
|
|
|
|
|
|
|
return xServiceManager->createInstanceWithArgumentsAndContext(
|
|
|
|
UNISTRING( "com.sun.star.setup.UpdateCheckUI" ),
|
|
|
|
aArgumentList, xContext );
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
uno::Reference<task::XInteractionHandler>
|
|
|
|
UpdateCheckJob::getInteractionHandler() const
|
|
|
|
{
|
|
|
|
uno::Reference<uno::XComponentContext> xContext(m_xContext);
|
|
|
|
|
|
|
|
if( !xContext.is() )
|
|
|
|
throw uno::RuntimeException(
|
|
|
|
UNISTRING( "UpdateCheckJob: empty component context" ), *this );
|
|
|
|
|
|
|
|
uno::Reference< lang::XMultiComponentFactory > xServiceManager(xContext->getServiceManager());
|
|
|
|
|
|
|
|
if( !xServiceManager.is() )
|
|
|
|
throw uno::RuntimeException(
|
|
|
|
UNISTRING( "UpdateCheckJob: unable to obtain service manager from component context" ), *this );
|
|
|
|
|
|
|
|
return uno::Reference<task::XInteractionHandler> (
|
|
|
|
xServiceManager->createInstanceWithContext(
|
|
|
|
UNISTRING( "com.sun.star.task.InteractionHandler" ),
|
|
|
|
xContext),
|
|
|
|
uno::UNO_QUERY_THROW);
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
uno::Reference<c3s::XSystemShellExecute>
|
|
|
|
UpdateCheckJob::getShellExecuter() const
|
|
|
|
{
|
|
|
|
uno::Reference<uno::XComponentContext> xContext(m_xContext);
|
|
|
|
|
|
|
|
if( !xContext.is() )
|
|
|
|
throw uno::RuntimeException(
|
|
|
|
UNISTRING( "UpdateCheckJob: empty component context" ), *this );
|
|
|
|
|
|
|
|
uno::Reference< lang::XMultiComponentFactory > xServiceManager(xContext->getServiceManager());
|
|
|
|
|
|
|
|
if( !xServiceManager.is() )
|
|
|
|
throw uno::RuntimeException(
|
|
|
|
UNISTRING( "UpdateCheckJob: unable to obtain service manager from component context" ), *this );
|
|
|
|
|
|
|
|
return uno::Reference<c3s::XSystemShellExecute> (
|
|
|
|
xServiceManager->createInstanceWithContext(
|
|
|
|
UNISTRING( "com.sun.star.system.SystemShellExecute" ),
|
|
|
|
xContext),
|
|
|
|
uno::UNO_QUERY_THROW);
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
rtl::OUString
|
|
|
|
UpdateCheckJob::getBuildId()
|
|
|
|
{
|
|
|
|
if( m_aBuildId.getLength() == 0 )
|
|
|
|
{
|
|
|
|
rtl::OUString aPath;
|
|
|
|
if( osl_getExecutableFile(&aPath.pData) == osl_Process_E_None )
|
|
|
|
{
|
|
|
|
sal_uInt32 lastIndex = aPath.lastIndexOf('/');
|
|
|
|
if ( lastIndex > 0 )
|
|
|
|
{
|
|
|
|
aPath = aPath.copy( 0, lastIndex+1 );
|
|
|
|
aPath += UNISTRING( SAL_CONFIGFILE( "version" ) );
|
|
|
|
}
|
|
|
|
|
|
|
|
rtl::Bootstrap aVersionFile(aPath);
|
|
|
|
aVersionFile.getFrom(UNISTRING("buildid"), m_aBuildId, rtl::OUString());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return m_aBuildId;
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
rtl::OUString
|
|
|
|
UpdateCheckJob::getProductName() const
|
|
|
|
{
|
|
|
|
rtl::OUString aProductName;
|
|
|
|
|
|
|
|
uno::Reference< container::XNameAccess > xNameAccess( getNameAccess(UNISTRING("org.openoffice.Setup/Product")) );
|
|
|
|
xNameAccess->getByName(UNISTRING("ooName")) >>= aProductName;
|
|
|
|
|
|
|
|
return aProductName;
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
2006-09-13 10:26:00 +00:00
|
|
|
rtl::OUString
|
|
|
|
UpdateCheckJob::getLocale() const
|
|
|
|
{
|
|
|
|
rtl::OUString aProductName;
|
|
|
|
|
|
|
|
uno::Reference< container::XNameAccess > xNameAccess( getNameAccess(UNISTRING("org.openoffice.Setup/L10N")) );
|
|
|
|
xNameAccess->getByName(UNISTRING("ooLocale")) >>= aProductName;
|
|
|
|
|
|
|
|
return aProductName;
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
2006-08-04 08:56:09 +00:00
|
|
|
void
|
|
|
|
UpdateCheckJob::runAsThread()
|
|
|
|
{
|
|
|
|
TimeValue tv = { 10, 0 };
|
|
|
|
|
|
|
|
// Initial wait to avoid doing further time consuming tasks during start-up
|
|
|
|
osl_waitCondition(m_hCondition, &tv);
|
|
|
|
|
|
|
|
// Might have been terminated meanwhile
|
|
|
|
if( sal_False == osl_scheduleThread(m_hThread) )
|
|
|
|
return;
|
|
|
|
|
|
|
|
try {
|
|
|
|
uno::Reference< container::XNameReplace > xCFGUpdate =
|
|
|
|
getUpdateAccess( UNISTRING("org.openoffice.Office.Jobs/Jobs/UpdateCheck/Arguments") );
|
|
|
|
|
|
|
|
while( sal_True == osl_scheduleThread(m_hThread) )
|
|
|
|
{
|
|
|
|
sal_Int64 last;
|
|
|
|
sal_Int64 offset;
|
|
|
|
sal_Bool bEnabled;
|
|
|
|
|
|
|
|
xCFGUpdate->getByName( UNISTRING("LastCheck") ) >>= last;
|
|
|
|
xCFGUpdate->getByName( UNISTRING("CheckInterval") ) >>= offset;
|
|
|
|
xCFGUpdate->getByName( UNISTRING("AutoCheckEnabled") ) >>= bEnabled;
|
|
|
|
|
|
|
|
if( bEnabled != sal_True )
|
|
|
|
{
|
|
|
|
osl_terminateThread(m_hThread);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
// last == 0 means check immediately
|
|
|
|
if( last > 0 )
|
|
|
|
{
|
|
|
|
TimeValue systime;
|
|
|
|
osl_getSystemTime(&systime);
|
|
|
|
|
|
|
|
// Go back to sleep until time has elapsed
|
|
|
|
sal_Int64 next = last + offset;
|
|
|
|
if( last + offset > systime.Seconds )
|
|
|
|
{
|
|
|
|
// This can not be > 32 Bit for now ..
|
|
|
|
tv.Seconds = static_cast< sal_Int32 > (next - systime.Seconds);
|
|
|
|
osl_waitCondition(m_hCondition, &tv);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
rtl::OUString aDownloadURL;
|
|
|
|
rtl::OUString aVersionFound;
|
|
|
|
|
|
|
|
if( hasInternetConnection() &&
|
|
|
|
checkForUpdates(m_xContext, uno::Reference< task::XInteractionHandler >(), aDownloadURL, aVersionFound) )
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* found updates for previous version are removed at startup, so
|
|
|
|
* we just compare the version info returned from the server
|
|
|
|
*/
|
|
|
|
|
|
|
|
if( aDownloadURL.getLength() > 0 )
|
|
|
|
{
|
|
|
|
rtl::OUString aPreviousVersionFound;
|
|
|
|
xCFGUpdate->getByName( UNISTRING("UpdateVersionFound") ) >>= aPreviousVersionFound;
|
|
|
|
|
|
|
|
if( ! aPreviousVersionFound.equals(aVersionFound) )
|
|
|
|
m_xUIService = getUIService(sal_True);
|
|
|
|
|
|
|
|
xCFGUpdate->replaceByName(UNISTRING("UpdateVersionFound"), uno::makeAny(aVersionFound));
|
|
|
|
xCFGUpdate->replaceByName(UNISTRING("DownloadURL"), uno::makeAny(aDownloadURL));
|
|
|
|
xCFGUpdate->replaceByName(UNISTRING("UpdateFoundFor"), uno::makeAny(getBuildId()));
|
|
|
|
}
|
|
|
|
|
|
|
|
TimeValue systime;
|
|
|
|
osl_getSystemTime(&systime);
|
|
|
|
sal_Int64 lastCheck = systime.Seconds;
|
|
|
|
|
|
|
|
xCFGUpdate->replaceByName(UNISTRING("LastCheck"), uno::makeAny(lastCheck));
|
|
|
|
|
|
|
|
uno::Reference< util::XChangesBatch > xChangesBatch(xCFGUpdate, uno::UNO_QUERY_THROW);
|
|
|
|
xChangesBatch->commitChanges();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Increase next by 1, 5, 15, 60, .. minutes
|
|
|
|
static const sal_Int16 nRetryInterval[] = { 60, 300, 900, 3600, 0 /* Ignored */ };
|
|
|
|
static sal_uInt8 n = 0;
|
|
|
|
|
|
|
|
if( n < sizeof(nRetryInterval) / sizeof(sal_Int16) )
|
|
|
|
++n;
|
|
|
|
|
|
|
|
tv.Seconds = nRetryInterval[n];
|
|
|
|
osl_waitCondition(m_hCondition, &tv);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
catch(const uno::Exception& e) {
|
|
|
|
// Silently catch all errors
|
|
|
|
OSL_TRACE( "Caught exception: %s\n thread terminated.\n",
|
|
|
|
rtl::OUStringToOString(e.Message, RTL_TEXTENCODING_UTF8).getStr() );
|
|
|
|
}
|
|
|
|
|
|
|
|
m_hThread = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
void
|
|
|
|
UpdateCheckJob::makeGlobal(const uno::Sequence<beans::NamedValue>& rNamedValues)
|
|
|
|
throw (uno::RuntimeException)
|
|
|
|
{
|
|
|
|
rtl::OUString aBuildId = getValue< rtl::OUString > (rNamedValues, "UpdateFoundFor");
|
|
|
|
|
|
|
|
// Clean up service data after update
|
|
|
|
if( aBuildId.getLength() > 0 && ! aBuildId.equals(getBuildId()) )
|
|
|
|
{
|
|
|
|
uno::Reference< container::XNameReplace > xCFGUpdate =
|
|
|
|
getUpdateAccess(UNISTRING("org.openoffice.Office.Jobs/Jobs/UpdateCheck/Arguments"));
|
|
|
|
|
|
|
|
uno::Any aEmptyAny = uno::makeAny( rtl::OUString() );
|
|
|
|
|
|
|
|
xCFGUpdate->replaceByName(UNISTRING("UpdateVersionFound"), aEmptyAny);
|
|
|
|
xCFGUpdate->replaceByName(UNISTRING("DownloadURL"), aEmptyAny);
|
|
|
|
xCFGUpdate->replaceByName(UNISTRING("UpdateFoundFor"), aEmptyAny);
|
|
|
|
|
|
|
|
uno::Reference< util::XChangesBatch > xChangesBatch(xCFGUpdate, uno::UNO_QUERY_THROW);
|
|
|
|
xChangesBatch->commitChanges();
|
|
|
|
|
|
|
|
aBuildId = rtl::OUString();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
sal_Bool isEnabled = getValue< sal_Bool > (rNamedValues, "AutoCheckEnabled");
|
|
|
|
if( isEnabled != sal_True )
|
|
|
|
return;
|
|
|
|
|
|
|
|
// If we found an update earlier, turn on menu bar icon
|
|
|
|
if( aBuildId.getLength() > 0 )
|
|
|
|
{
|
|
|
|
m_xUIService = getUIService(sal_False);
|
|
|
|
OSL_TRACE( "UI Service initialization %s\n", m_xUIService.is() ? "succeeded" : "failed" );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Initialize thread resources ..
|
|
|
|
uno::Reference< lang::XComponent > xComponent(m_xContext, uno::UNO_QUERY_THROW);
|
|
|
|
|
|
|
|
m_hCondition = osl_createCondition();
|
|
|
|
if( m_hCondition == 0 )
|
|
|
|
throw uno::RuntimeException(
|
|
|
|
UNISTRING( "UpdateCheckJob: unable to create condition object" ), *this);
|
|
|
|
|
|
|
|
m_hThread = osl_createSuspendedThread( myThreadFunc, this );
|
|
|
|
if( m_hThread == 0 )
|
|
|
|
throw uno::RuntimeException(
|
|
|
|
UNISTRING( "UpdateCheckJob: unable to create thread object" ), *this);
|
|
|
|
|
|
|
|
// .. , hook up as terminate listener and remember this instace before ..
|
|
|
|
xComponent->addEventListener(this);
|
|
|
|
g_aInstance = static_cast< cppu::OWeakObject *> (this);
|
|
|
|
|
|
|
|
#ifdef WNT
|
|
|
|
rtl::OUString aPath;
|
|
|
|
if( osl_getExecutableFile(&aPath.pData) == osl_Process_E_None )
|
|
|
|
{
|
|
|
|
sal_uInt32 lastIndex = aPath.lastIndexOf('/');
|
|
|
|
if ( lastIndex > 0 )
|
|
|
|
{
|
|
|
|
aPath = aPath.copy( 0, lastIndex+1 );
|
|
|
|
aPath += UNISTRING( "onlinecheck" );
|
|
|
|
}
|
|
|
|
|
|
|
|
m_hModule = osl_loadModule(aPath.pData, SAL_LOADMODULE_DEFAULT);
|
|
|
|
|
|
|
|
if( m_hModule )
|
|
|
|
m_pHasInternetConnection = reinterpret_cast < sal_Bool (*) () > (
|
|
|
|
osl_getFunctionSymbol(m_hModule,
|
|
|
|
UNISTRING("hasInternetConnection").pData));
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// actually run the thread
|
|
|
|
osl_resumeThread(m_hThread);
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
uno::Any
|
|
|
|
UpdateCheckJob::execute(const uno::Sequence<beans::NamedValue>& namedValues)
|
|
|
|
throw (lang::IllegalArgumentException, uno::Exception)
|
|
|
|
{
|
|
|
|
uno::Sequence<beans::NamedValue> aConfig =
|
|
|
|
getValue< uno::Sequence<beans::NamedValue> > (namedValues, "JobConfig");
|
|
|
|
|
2006-09-13 10:26:00 +00:00
|
|
|
// Localization in extendable sets not yet supported
|
|
|
|
rtl::OString aLocale = OUStringToOString(getLocale(), RTL_TEXTENCODING_ASCII_US);
|
|
|
|
try
|
|
|
|
{
|
|
|
|
rtl::OString aKey = "BubbleHeading_";
|
|
|
|
aKey += aLocale;
|
|
|
|
m_aBubbleHeading = getValue< rtl::OUString > (aConfig, aKey.getStr());
|
|
|
|
aKey = "BubbleText_";
|
|
|
|
aKey += aLocale;
|
|
|
|
m_aBubbleText = getValue< rtl::OUString > (aConfig, aKey.getStr());
|
|
|
|
}
|
|
|
|
catch( uno::RuntimeException& )
|
|
|
|
{
|
|
|
|
// fallback to en-US
|
|
|
|
m_aBubbleHeading = getValue< rtl::OUString > (aConfig, "BubbleHeading_en-US");
|
|
|
|
m_aBubbleText = getValue< rtl::OUString > (aConfig, "BubbleText_en-US");
|
|
|
|
}
|
|
|
|
|
|
|
|
// m_aBubbleHeading = getValue< rtl::OUString > (aConfig, "BubbleHeading");
|
|
|
|
// m_aBubbleText = getValue< rtl::OUString > (aConfig, "BubbleText");
|
2006-08-04 08:56:09 +00:00
|
|
|
|
|
|
|
/* Determine the way we got invoked here -
|
|
|
|
* see Developers Guide Chapter "4.7.2 Jobs" to understand the magic
|
|
|
|
*/
|
|
|
|
|
|
|
|
uno::Sequence<beans::NamedValue> aEnvironment =
|
|
|
|
getValue< uno::Sequence<beans::NamedValue> > (namedValues, "Environment");
|
|
|
|
|
|
|
|
rtl::OUString aEventName = getValue< rtl::OUString > (aEnvironment, "EventName");
|
|
|
|
|
|
|
|
if( aEventName.equalsAscii("onFirstVisibleTask") )
|
|
|
|
{
|
|
|
|
makeGlobal(aConfig);
|
|
|
|
}
|
|
|
|
else if( aConfig.getLength() > 0 )
|
|
|
|
{
|
|
|
|
uno::Reference< container::XNameReplace > xCFGUpdate =
|
|
|
|
getUpdateAccess( UNISTRING("org.openoffice.Office.Jobs/Jobs/UpdateCheck/Arguments") );
|
|
|
|
|
|
|
|
rtl::OUString aDownloadURL;
|
|
|
|
rtl::OUString aVersionFound;
|
|
|
|
|
|
|
|
if( checkForUpdates(m_xContext, getInteractionHandler(), aDownloadURL, aVersionFound) )
|
|
|
|
{
|
|
|
|
if( aDownloadURL.getLength() > 0 )
|
|
|
|
{
|
|
|
|
xCFGUpdate->replaceByName(UNISTRING("UpdateVersionFound"), uno::makeAny(aVersionFound));
|
|
|
|
xCFGUpdate->replaceByName(UNISTRING("DownloadURL"), uno::makeAny(aDownloadURL));
|
|
|
|
xCFGUpdate->replaceByName(UNISTRING("UpdateFoundFor"), uno::makeAny(getBuildId()));
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TimeValue systime;
|
|
|
|
osl_getSystemTime(&systime);
|
|
|
|
sal_Int64 lastCheck = systime.Seconds;
|
|
|
|
|
|
|
|
xCFGUpdate->replaceByName(UNISTRING("LastCheck"), uno::makeAny(lastCheck));
|
|
|
|
|
|
|
|
uno::Reference< util::XChangesBatch > xChangesBatch(xCFGUpdate, uno::UNO_QUERY_THROW);
|
|
|
|
xChangesBatch->commitChanges();
|
|
|
|
|
|
|
|
// setValue< sal_Int64 > (aConfig, "NextCheck", nOffset + systime.Seconds);
|
|
|
|
|
|
|
|
|
|
|
|
frame::DispatchResultEvent aResultEvent(*this, frame::DispatchResultState::SUCCESS, uno::makeAny(aDownloadURL));
|
|
|
|
/*
|
|
|
|
uno::Sequence< beans::NamedValue > aResult(2);
|
|
|
|
aResult[0].Name = UNISTRING("SaveArguments");
|
|
|
|
aResult[0].Value = uno::makeAny(aConfig);
|
|
|
|
*/
|
|
|
|
uno::Sequence< beans::NamedValue > aResult(1);
|
|
|
|
aResult[0].Name = UNISTRING("SendDispatchResult");
|
|
|
|
aResult[0].Value = uno::makeAny(aResultEvent);
|
|
|
|
|
|
|
|
return uno::makeAny(aResult);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
uno::Sequence< beans::NamedValue > aResult(1);
|
|
|
|
aResult[0].Name = UNISTRING("SendDispatchResult");
|
|
|
|
aResult[0].Value = uno::makeAny(sal_False);
|
|
|
|
|
|
|
|
return uno::makeAny(aResult);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
uno::Reference< container::XNameAccess > xCFGAccess =
|
|
|
|
getNameAccess( UNISTRING("org.openoffice.Office.Jobs/Jobs/UpdateCheck/Arguments") );
|
|
|
|
|
|
|
|
rtl::OUString aDownloadURL;
|
|
|
|
xCFGAccess->getByName( UNISTRING("DownloadURL") ) >>= aDownloadURL;
|
|
|
|
|
|
|
|
uno::Reference< c3s::XSystemShellExecute > xShellExecute( getShellExecuter() );
|
|
|
|
xShellExecute->execute( aDownloadURL, ::rtl::OUString(), c3s::SystemShellExecuteFlags::DEFAULTS );
|
|
|
|
}
|
|
|
|
|
|
|
|
return uno::Any();
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
rtl::OUString SAL_CALL
|
|
|
|
UpdateCheckJob::getImplementationName() throw (uno::RuntimeException)
|
|
|
|
{
|
|
|
|
return getImplName();
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
uno::Sequence< rtl::OUString > SAL_CALL
|
|
|
|
UpdateCheckJob::getSupportedServiceNames() throw (uno::RuntimeException)
|
|
|
|
{
|
|
|
|
return getServiceNames();
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
sal_Bool SAL_CALL
|
|
|
|
UpdateCheckJob::supportsService( rtl::OUString const & serviceName ) throw (uno::RuntimeException)
|
|
|
|
{
|
|
|
|
uno::Sequence< rtl::OUString > aServiceNameList = getServiceNames();
|
|
|
|
|
|
|
|
for( sal_Int32 n=0; n < aServiceNameList.getLength(); n++ )
|
|
|
|
if( aServiceNameList[n].equals(serviceName) )
|
|
|
|
return sal_True;
|
|
|
|
|
|
|
|
return sal_False;
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
void SAL_CALL
|
|
|
|
UpdateCheckJob::disposing(const lang::EventObject&) throw (uno::RuntimeException)
|
|
|
|
{
|
|
|
|
g_aInstance.clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
} // anonymous namespace
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
extern "C" void SAL_CALL myThreadFunc( void* p )
|
|
|
|
{
|
|
|
|
reinterpret_cast< UpdateCheckJob * > (p)->runAsThread();
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
static uno::Reference<uno::XInterface> SAL_CALL
|
|
|
|
createJobInstance(const uno::Reference<uno::XComponentContext>& xContext)
|
|
|
|
{
|
|
|
|
return * new UpdateCheckJob(xContext);
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
static uno::Reference<uno::XInterface> SAL_CALL
|
|
|
|
createConfigInstance(const uno::Reference<uno::XComponentContext>& xContext)
|
|
|
|
{
|
|
|
|
return * new UpdateCheckConfig(xContext);
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
static const cppu::ImplementationEntry kImplementations_entries[] =
|
|
|
|
{
|
|
|
|
{
|
|
|
|
createJobInstance,
|
|
|
|
UpdateCheckJob::getImplName,
|
|
|
|
UpdateCheckJob::getServiceNames,
|
|
|
|
cppu::createSingleComponentFactory,
|
|
|
|
NULL,
|
|
|
|
0
|
|
|
|
},
|
|
|
|
{
|
|
|
|
createConfigInstance,
|
|
|
|
UpdateCheckConfig::getImplName,
|
|
|
|
UpdateCheckConfig::getServiceNames,
|
|
|
|
cppu::createSingleComponentFactory,
|
|
|
|
NULL,
|
|
|
|
0
|
|
|
|
},
|
|
|
|
{ NULL, NULL, NULL, NULL, NULL, 0 }
|
|
|
|
} ;
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
extern "C" void SAL_CALL
|
|
|
|
component_getImplementationEnvironment( const sal_Char **aEnvTypeName, uno_Environment **)
|
|
|
|
{
|
|
|
|
*aEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME ;
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
extern "C" sal_Bool SAL_CALL
|
|
|
|
component_writeInfo(void *pServiceManager, void *pRegistryKey)
|
|
|
|
{
|
|
|
|
return cppu::component_writeInfoHelper(
|
|
|
|
pServiceManager,
|
|
|
|
pRegistryKey,
|
|
|
|
kImplementations_entries
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
extern "C" void *
|
|
|
|
component_getFactory(const sal_Char *pszImplementationName, void *pServiceManager, void *pRegistryKey)
|
|
|
|
{
|
|
|
|
return cppu::component_getFactoryHelper(
|
|
|
|
pszImplementationName,
|
|
|
|
pServiceManager,
|
|
|
|
pRegistryKey,
|
|
|
|
kImplementations_entries) ;
|
|
|
|
}
|
|
|
|
|