bump product version to 6.3.0.0.beta1
[LibreOffice.git] / extensions / source / update / check / updatecheckjob.cxx
blob298046485fde52d67fa0ed83877c8815acfc734e
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <sal/config.h>
22 #include "updatecheck.hxx"
23 #include "updatecheckconfig.hxx"
24 #include "updatehdl.hxx"
25 #include "updateprotocol.hxx"
27 #include <memory>
28 #include <cppuhelper/implbase.hxx>
29 #include <cppuhelper/implementationentry.hxx>
30 #include <cppuhelper/supportsservice.hxx>
31 #include <sal/log.hxx>
32 #include <tools/diagnose_ex.h>
34 #include <com/sun/star/frame/Desktop.hpp>
35 #include <com/sun/star/frame/XTerminateListener.hpp>
36 #include <com/sun/star/task/XJob.hpp>
38 namespace beans = com::sun::star::beans ;
39 namespace frame = com::sun::star::frame ;
40 namespace lang = com::sun::star::lang ;
41 namespace task = com::sun::star::task ;
42 namespace uno = com::sun::star::uno ;
44 namespace
47 class InitUpdateCheckJobThread : public osl::Thread
49 public:
50 InitUpdateCheckJobThread( const uno::Reference< uno::XComponentContext > &xContext,
51 const uno::Sequence< beans::NamedValue > &xParameters,
52 bool bShowDialog );
54 virtual void SAL_CALL run() override;
56 void setTerminating();
58 private:
59 osl::Condition m_aCondition;
60 uno::Reference<uno::XComponentContext> m_xContext;
61 uno::Sequence<beans::NamedValue> m_xParameters;
62 bool m_bShowDialog;
63 bool m_bTerminating;
66 class UpdateCheckJob :
67 public ::cppu::WeakImplHelper< task::XJob, lang::XServiceInfo, frame::XTerminateListener >
69 virtual ~UpdateCheckJob() override;
71 public:
73 UpdateCheckJob(
74 css::uno::Reference<css::uno::XComponentContext> const & context,
75 css::uno::Reference<css::frame::XDesktop2> const & desktop):
76 m_xContext(context), m_xDesktop(desktop)
79 static uno::Sequence< OUString > getServiceNames();
80 static OUString getImplName();
82 // XJob
83 virtual uno::Any SAL_CALL execute(const uno::Sequence<beans::NamedValue>&) override;
85 // XServiceInfo
86 virtual OUString SAL_CALL getImplementationName() override;
87 virtual sal_Bool SAL_CALL supportsService(OUString const & serviceName) override;
88 virtual uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override;
90 // XEventListener
91 virtual void SAL_CALL disposing( css::lang::EventObject const & evt ) override;
93 // XTerminateListener
94 virtual void SAL_CALL queryTermination( lang::EventObject const & evt ) override;
95 virtual void SAL_CALL notifyTermination( lang::EventObject const & evt ) override;
97 private:
98 uno::Reference<uno::XComponentContext> m_xContext;
99 uno::Reference< frame::XDesktop2 > m_xDesktop;
100 std::unique_ptr< InitUpdateCheckJobThread > m_pInitThread;
102 void handleExtensionUpdates( const uno::Sequence< beans::NamedValue > &rListProp );
103 void terminateAndJoinThread();
106 InitUpdateCheckJobThread::InitUpdateCheckJobThread(
107 const uno::Reference< uno::XComponentContext > &xContext,
108 const uno::Sequence< beans::NamedValue > &xParameters,
109 bool bShowDialog ) :
110 m_xContext( xContext ),
111 m_xParameters( xParameters ),
112 m_bShowDialog( bShowDialog ),
113 m_bTerminating( false )
115 create();
119 void SAL_CALL InitUpdateCheckJobThread::run()
121 osl_setThreadName("InitUpdateCheckJobThread");
123 if (!m_bShowDialog) {
124 TimeValue tv = { 25, 0 };
125 m_aCondition.wait( &tv );
126 if ( m_bTerminating )
127 return;
130 try {
131 rtl::Reference< UpdateCheck > aController( UpdateCheck::get() );
132 aController->initialize( m_xParameters, m_xContext );
134 if ( m_bShowDialog )
135 aController->showDialog( true );
136 } catch (const uno::Exception &) {
137 css::uno::Any ex( cppu::getCaughtException() );
138 // fdo#64962 - don't bring the app down on some unexpected exception.
139 SAL_WARN("extensions.update", "Caught init update exception, thread terminated. " << exceptionToString(ex) );
143 void InitUpdateCheckJobThread::setTerminating() {
144 m_bTerminating = true;
145 m_aCondition.set();
148 UpdateCheckJob::~UpdateCheckJob()
152 uno::Sequence< OUString >
153 UpdateCheckJob::getServiceNames()
155 uno::Sequence< OUString > aServiceList { "com.sun.star.setup.UpdateCheck" };
156 return aServiceList;
160 OUString
161 UpdateCheckJob::getImplName()
163 return OUString("vnd.sun.UpdateCheck");
167 uno::Any
168 UpdateCheckJob::execute(const uno::Sequence<beans::NamedValue>& namedValues)
170 for ( sal_Int32 n=namedValues.getLength(); n-- > 0; )
172 if ( namedValues[ n ].Name == "DynamicData" )
174 uno::Sequence<beans::NamedValue> aListProp;
175 if ( namedValues[n].Value >>= aListProp )
177 for ( sal_Int32 i=aListProp.getLength(); i-- > 0; )
179 if ( aListProp[ i ].Name == "updateList" )
181 handleExtensionUpdates( aListProp );
182 return uno::Any();
189 uno::Sequence<beans::NamedValue> aConfig =
190 getValue< uno::Sequence<beans::NamedValue> > (namedValues, "JobConfig");
192 /* Determine the way we got invoked here -
193 * see Developers Guide Chapter "4.7.2 Jobs" to understand the magic
196 uno::Sequence<beans::NamedValue> aEnvironment =
197 getValue< uno::Sequence<beans::NamedValue> > (namedValues, "Environment");
199 OUString aEventName = getValue< OUString > (aEnvironment, "EventName");
201 m_pInitThread.reset(
202 new InitUpdateCheckJobThread(
203 m_xContext, aConfig,
204 aEventName != "onFirstVisibleTask"));
206 return uno::Any();
210 void UpdateCheckJob::handleExtensionUpdates( const uno::Sequence< beans::NamedValue > &rListProp )
212 try {
213 uno::Sequence< uno::Sequence< OUString > > aList =
214 getValue< uno::Sequence< uno::Sequence< OUString > > > ( rListProp, "updateList" );
215 bool bPrepareOnly = getValue< bool > ( rListProp, "prepareOnly" );
217 // we will first store any new found updates and then check, if there are any
218 // pending updates.
219 storeExtensionUpdateInfos( m_xContext, aList );
221 if ( bPrepareOnly )
222 return;
224 bool bHasUpdates = checkForPendingUpdates( m_xContext );
226 rtl::Reference<UpdateCheck> aController( UpdateCheck::get() );
227 if ( ! aController.is() )
228 return;
230 aController->setHasExtensionUpdates( bHasUpdates );
232 if ( ! aController->hasOfficeUpdate() )
234 if ( bHasUpdates )
235 aController->setUIState( UPDATESTATE_EXT_UPD_AVAIL, true );
236 else
237 aController->setUIState( UPDATESTATE_NO_UPDATE_AVAIL, true );
240 catch( const uno::Exception& )
242 css::uno::Any ex( cppu::getCaughtException() );
243 SAL_WARN("extensions.update", "Caught exception, thread terminated. " << exceptionToString(ex));
248 OUString SAL_CALL
249 UpdateCheckJob::getImplementationName()
251 return getImplName();
255 uno::Sequence< OUString > SAL_CALL
256 UpdateCheckJob::getSupportedServiceNames()
258 return getServiceNames();
261 sal_Bool SAL_CALL
262 UpdateCheckJob::supportsService( OUString const & serviceName )
264 return cppu::supportsService(this, serviceName);
268 // XEventListener
269 void SAL_CALL UpdateCheckJob::disposing( lang::EventObject const & rEvt )
271 bool shutDown = ( rEvt.Source == m_xDesktop );
273 if ( shutDown && m_xDesktop.is() )
275 terminateAndJoinThread();
276 m_xDesktop->removeTerminateListener( this );
277 m_xDesktop.clear();
282 // XTerminateListener
283 void SAL_CALL UpdateCheckJob::queryTermination( lang::EventObject const & )
287 void UpdateCheckJob::terminateAndJoinThread()
289 if (m_pInitThread != nullptr)
291 m_pInitThread->setTerminating();
292 m_pInitThread->join();
293 m_pInitThread.reset();
297 void SAL_CALL UpdateCheckJob::notifyTermination( lang::EventObject const & )
299 terminateAndJoinThread();
302 } // anonymous namespace
304 static uno::Reference<uno::XInterface>
305 createJobInstance(const uno::Reference<uno::XComponentContext>& xContext)
307 css::uno::Reference<css::frame::XDesktop2> desktop(
308 css::frame::Desktop::create(xContext));
309 rtl::Reference<UpdateCheckJob> job(new UpdateCheckJob(xContext, desktop));
310 desktop->addTerminateListener(job.get());
311 return static_cast<cppu::OWeakObject *>(job.get());
315 static uno::Reference<uno::XInterface>
316 createConfigInstance(const uno::Reference<uno::XComponentContext>& xContext)
318 return *UpdateCheckConfig::get(xContext, *UpdateCheck::get());
322 static const cppu::ImplementationEntry kImplementations_entries[] =
325 createJobInstance,
326 UpdateCheckJob::getImplName,
327 UpdateCheckJob::getServiceNames,
328 cppu::createSingleComponentFactory,
329 nullptr,
333 createConfigInstance,
334 UpdateCheckConfig::getImplName,
335 UpdateCheckConfig::getServiceNames,
336 cppu::createSingleComponentFactory,
337 nullptr,
340 { nullptr, nullptr, nullptr, nullptr, nullptr, 0 }
344 extern "C" SAL_DLLPUBLIC_EXPORT void * updchk_component_getFactory(const sal_Char *pszImplementationName, void *pServiceManager, void *pRegistryKey)
346 return cppu::component_getFactoryHelper(
347 pszImplementationName,
348 pServiceManager,
349 pRegistryKey,
350 kImplementations_entries) ;
353 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */