/************************************************************** * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * *************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_extensions.hxx" #include #include "updatecheck.hxx" #include "updatecheckconfig.hxx" #include "updatehdl.hxx" #include "updateprotocol.hxx" #include #include #include "com/sun/star/frame/XDesktop.hpp" #include "com/sun/star/frame/XTerminateListener.hpp" #include namespace beans = com::sun::star::beans ; namespace frame = com::sun::star::frame ; namespace lang = com::sun::star::lang ; namespace task = com::sun::star::task ; namespace uno = com::sun::star::uno ; #define UNISTRING(s) rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(s)) namespace { class InitUpdateCheckJobThread : public osl::Thread { public: InitUpdateCheckJobThread( const uno::Reference< uno::XComponentContext > &xContext, const uno::Sequence< beans::NamedValue > &xParameters, bool bShowDialog ); virtual void SAL_CALL run(); void setTerminating(); private: osl::Condition m_aCondition; uno::Reference m_xContext; uno::Sequence m_xParameters; bool m_bShowDialog; bool m_bTerminating; }; class UpdateCheckJob : public ::cppu::WeakImplHelper3< task::XJob, lang::XServiceInfo, frame::XTerminateListener > { virtual ~UpdateCheckJob(); public: UpdateCheckJob(const uno::Reference& xContext); 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&) 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); // XEventListener virtual void SAL_CALL disposing( ::com::sun::star::lang::EventObject const & evt ) throw (::com::sun::star::uno::RuntimeException); // XTerminateListener virtual void SAL_CALL queryTermination( lang::EventObject const & evt ) throw ( frame::TerminationVetoException, uno::RuntimeException ); virtual void SAL_CALL notifyTermination( lang::EventObject const & evt ) throw ( uno::RuntimeException ); private: uno::Reference m_xContext; uno::Reference< frame::XDesktop > m_xDesktop; std::auto_ptr< InitUpdateCheckJobThread > m_pInitThread; void handleExtensionUpdates( const uno::Sequence< beans::NamedValue > &rListProp ); }; //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ InitUpdateCheckJobThread::InitUpdateCheckJobThread( const uno::Reference< uno::XComponentContext > &xContext, const uno::Sequence< beans::NamedValue > &xParameters, bool bShowDialog ) : m_xContext( xContext ), m_xParameters( xParameters ), m_bShowDialog( bShowDialog ), m_bTerminating( false ) { create(); } //------------------------------------------------------------------------------ void SAL_CALL InitUpdateCheckJobThread::run() { if (!m_bShowDialog) { TimeValue tv = { 25, 0 }; m_aCondition.wait( &tv ); if ( m_bTerminating ) return; } rtl::Reference< UpdateCheck > aController( UpdateCheck::get() ); aController->initialize( m_xParameters, m_xContext ); if ( m_bShowDialog ) aController->showDialog( true ); } void InitUpdateCheckJobThread::setTerminating() { m_bTerminating = true; m_aCondition.set(); } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ UpdateCheckJob::UpdateCheckJob( const uno::Reference& xContext ) : m_xContext(xContext) { m_xDesktop.set( xContext->getServiceManager()->createInstanceWithContext( UNISTRING("com.sun.star.frame.Desktop"), xContext ), uno::UNO_QUERY ); if ( m_xDesktop.is() ) m_xDesktop->addTerminateListener( this ); } //------------------------------------------------------------------------------ UpdateCheckJob::~UpdateCheckJob() { } //------------------------------------------------------------------------------ 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::Any UpdateCheckJob::execute(const uno::Sequence& namedValues) throw (lang::IllegalArgumentException, uno::Exception) { for ( sal_Int32 n=namedValues.getLength(); n-- > 0; ) { if ( namedValues[ n ].Name.equalsAscii( "DynamicData" ) ) { uno::Sequence aListProp; if ( namedValues[n].Value >>= aListProp ) { for ( sal_Int32 i=aListProp.getLength(); i-- > 0; ) { if ( aListProp[ i ].Name.equalsAscii( "updateList" ) ) { handleExtensionUpdates( aListProp ); return uno::Any(); } } } } } uno::Sequence aConfig = getValue< uno::Sequence > (namedValues, "JobConfig"); /* Determine the way we got invoked here - * see Developers Guide Chapter "4.7.2 Jobs" to understand the magic */ uno::Sequence aEnvironment = getValue< uno::Sequence > (namedValues, "Environment"); rtl::OUString aEventName = getValue< rtl::OUString > (aEnvironment, "EventName"); m_pInitThread.reset( new InitUpdateCheckJobThread( m_xContext, aConfig, !aEventName.equalsAscii("onFirstVisibleTask"))); return uno::Any(); } //------------------------------------------------------------------------------ void UpdateCheckJob::handleExtensionUpdates( const uno::Sequence< beans::NamedValue > &rListProp ) { try { uno::Sequence< uno::Sequence< rtl::OUString > > aList = getValue< uno::Sequence< uno::Sequence< rtl::OUString > > > ( rListProp, "updateList" ); bool bPrepareOnly = getValue< bool > ( rListProp, "prepareOnly" ); // we will first store any new found updates and then check, if there are any // pending updates. storeExtensionUpdateInfos( m_xContext, aList ); if ( bPrepareOnly ) return; bool bHasUpdates = checkForPendingUpdates( m_xContext ); rtl::Reference aController( UpdateCheck::get() ); if ( ! aController.is() ) return; aController->setHasExtensionUpdates( bHasUpdates ); if ( ! aController->hasOfficeUpdate() ) { if ( bHasUpdates ) aController->setUIState( UPDATESTATE_EXT_UPD_AVAIL, true ); else aController->setUIState( UPDATESTATE_NO_UPDATE_AVAIL, true ); } } catch( const uno::Exception& e ) { OSL_TRACE( "Caught exception: %s\n thread terminated.\n", rtl::OUStringToOString(e.Message, RTL_TEXTENCODING_UTF8).getStr()); } } //------------------------------------------------------------------------------ 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; } //------------------------------------------------------------------------------ // XEventListener void SAL_CALL UpdateCheckJob::disposing( lang::EventObject const & rEvt ) throw ( uno::RuntimeException ) { bool shutDown = ( rEvt.Source == m_xDesktop ); if ( shutDown && m_xDesktop.is() ) { m_xDesktop->removeTerminateListener( this ); m_xDesktop.clear(); } } //------------------------------------------------------------------------------ // XTerminateListener void SAL_CALL UpdateCheckJob::queryTermination( lang::EventObject const & ) throw ( frame::TerminationVetoException, uno::RuntimeException ) { } //------------------------------------------------------------------------------ void SAL_CALL UpdateCheckJob::notifyTermination( lang::EventObject const & ) throw ( uno::RuntimeException ) { if ( m_pInitThread.get() != 0 ) { m_pInitThread->setTerminating(); m_pInitThread->join(); } } } // anonymous namespace //------------------------------------------------------------------------------ static uno::Reference SAL_CALL createJobInstance(const uno::Reference& xContext) { return *new UpdateCheckJob(xContext); } //------------------------------------------------------------------------------ static uno::Reference SAL_CALL createConfigInstance(const uno::Reference& xContext) { return *UpdateCheckConfig::get(xContext, *UpdateCheck::get()); } //------------------------------------------------------------------------------ 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" void * component_getFactory(const sal_Char *pszImplementationName, void *pServiceManager, void *pRegistryKey) { return cppu::component_getFactoryHelper( pszImplementationName, pServiceManager, pRegistryKey, kImplementations_entries) ; }