| /************************************************************** |
| * |
| * 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 <memory> |
| |
| #include "updatecheck.hxx" |
| #include "updatecheckconfig.hxx" |
| #include "updatehdl.hxx" |
| #include "updateprotocol.hxx" |
| |
| #include <cppuhelper/implbase3.hxx> |
| #include <cppuhelper/implementationentry.hxx> |
| |
| #include "com/sun/star/frame/XDesktop.hpp" |
| #include "com/sun/star/frame/XTerminateListener.hpp" |
| #include <com/sun/star/task/XJob.hpp> |
| |
| 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<uno::XComponentContext> m_xContext; |
| uno::Sequence<beans::NamedValue> 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<uno::XComponentContext>& 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<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); |
| |
| // 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<uno::XComponentContext> 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<uno::XComponentContext>& 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<beans::NamedValue>& namedValues) |
| throw (lang::IllegalArgumentException, uno::Exception) |
| { |
| for ( sal_Int32 n=namedValues.getLength(); n-- > 0; ) |
| { |
| if ( namedValues[ n ].Name.equalsAscii( "DynamicData" ) ) |
| { |
| uno::Sequence<beans::NamedValue> 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<beans::NamedValue> aConfig = |
| getValue< uno::Sequence<beans::NamedValue> > (namedValues, "JobConfig"); |
| |
| /* 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"); |
| |
| 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<UpdateCheck> 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<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 *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) ; |
| } |