Update ooo320-m1
[ooovba.git] / extensions / source / update / check / updatecheck.cxx
blobfd9e8cae962973b20f304f1183af747d8b490703
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: updatecheck.cxx,v $
11 * This file is part of OpenOffice.org.
13 * OpenOffice.org is free software: you can redistribute it and/or modify
14 * it under the terms of the GNU Lesser General Public License version 3
15 * only, as published by the Free Software Foundation.
17 * OpenOffice.org is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU Lesser General Public License version 3 for more details
21 * (a copy is included in the LICENSE file that accompanied this code).
23 * You should have received a copy of the GNU Lesser General Public License
24 * version 3 along with OpenOffice.org. If not, see
25 * <http://www.openoffice.org/license.html>
26 * for a copy of the LGPLv3 License.
28 ************************************************************************/
30 // MARKER(update_precomp.py): autogen include statement, do not remove
31 #include "precompiled_extensions.hxx"
33 #include "updatecheck.hxx"
35 #include <cppuhelper/implbase1.hxx>
36 #include <com/sun/star/beans/XFastPropertySet.hpp>
37 #include <com/sun/star/lang/XComponent.hpp>
38 #include <com/sun/star/frame/XDesktop.hpp>
39 #include <com/sun/star/frame/XFrame.hpp>
40 #include <com/sun/star/frame/DispatchResultEvent.hpp>
41 #include <com/sun/star/frame/DispatchResultState.hpp>
42 #include <com/sun/star/system/XSystemShellExecute.hpp>
43 #include <com/sun/star/system/SystemShellExecuteFlags.hpp>
44 #include <com/sun/star/task/XJob.hpp>
45 #include <com/sun/star/task/XJobExecutor.hpp>
47 // #include <comphelper/processfactory.hxx>
49 #include <rtl/ustrbuf.hxx>
51 #include <rtl/bootstrap.hxx>
52 #include <osl/process.h>
53 #include <osl/module.hxx>
54 #include <osl/file.hxx>
56 #ifdef WNT
57 #ifdef _MSC_VER
58 #pragma warning(push,1) // disable warnings within system headers
59 //#pragma warning(disable: 4917)
60 #endif
61 #include <objbase.h>
62 #ifdef _MSC_VER
63 #pragma warning(pop)
64 #endif
65 #endif
67 #include "updateprotocol.hxx"
68 #include "updatecheckconfig.hxx"
70 namespace awt = com::sun::star::awt ;
71 namespace beans = com::sun::star::beans ;
72 namespace container = com::sun::star::container ;
73 namespace deployment = com::sun::star::deployment ;
74 namespace frame = com::sun::star::frame ;
75 namespace lang = com::sun::star::lang ;
76 namespace c3s = com::sun::star::system ;
77 namespace task = com::sun::star::task ;
78 namespace util = com::sun::star::util ;
79 namespace uno = com::sun::star::uno ;
81 #define UNISTRING(s) rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(s))
83 #define PROPERTY_TITLE UNISTRING("BubbleHeading")
84 #define PROPERTY_TEXT UNISTRING("BubbleText")
85 #define PROPERTY_IMAGE UNISTRING("BubbleImageURL")
86 #define PROPERTY_SHOW_BUBBLE UNISTRING("BubbleVisible")
87 #define PROPERTY_CLICK_HDL UNISTRING("MenuClickHDL")
88 #define PROPERTY_DEFAULT_TITLE UNISTRING("DefaultHeading")
89 #define PROPERTY_DEFAULT_TEXT UNISTRING("DefaultText")
90 #define PROPERTY_SHOW_MENUICON UNISTRING("MenuIconVisible")
92 //------------------------------------------------------------------------------
94 // Returns the URL of the release note for the given position
95 rtl::OUString getReleaseNote(const UpdateInfo& rInfo, sal_uInt8 pos, bool autoDownloadEnabled)
97 std::vector< ReleaseNote >::const_iterator iter = rInfo.ReleaseNotes.begin();
98 while( iter != rInfo.ReleaseNotes.end() )
100 if( pos == iter->Pos )
102 if( (pos > 2) || !autoDownloadEnabled || ! (iter->URL2.getLength() > 0) )
103 return iter->URL;
105 else if( (pos == iter->Pos2) && ((1 == iter->Pos) || (2 == iter->Pos)) && autoDownloadEnabled )
106 return iter->URL2;
108 ++iter;
111 return rtl::OUString();
114 //------------------------------------------------------------------------------
116 namespace
119 static inline rtl::OUString getBuildId()
121 rtl::OUString aPathVal(UNISTRING("${$OOO_BASE_DIR/program/" SAL_CONFIGFILE("version") ":buildid}"));
122 rtl::Bootstrap::expandMacros(aPathVal);
123 return aPathVal;
126 //------------------------------------------------------------------------------
127 static inline rtl::OUString getBaseInstallation()
129 rtl::OUString aPathVal(UNISTRING("${$BRAND_BASE_DIR/program/" SAL_CONFIGFILE("bootstrap") ":BaseInstallation}"));
130 rtl::Bootstrap::expandMacros(aPathVal);
131 return aPathVal;
134 //------------------------------------------------------------------------------
136 inline bool isObsoleteUpdateInfo(const rtl::OUString& rBuildId)
138 return sal_True != rBuildId.equals(getBuildId()) && rBuildId.getLength() > 0;
142 //------------------------------------------------------------------------------
144 rtl::OUString getImageFromFileName(const rtl::OUString& aFile)
146 #ifndef WNT
147 rtl::OUString aUnpackPath;
148 if( osl_getExecutableFile(&aUnpackPath.pData) == osl_Process_E_None )
150 sal_uInt32 lastIndex = aUnpackPath.lastIndexOf('/');
151 if ( lastIndex > 0 )
153 aUnpackPath = aUnpackPath.copy( 0, lastIndex+1 );
154 aUnpackPath += UNISTRING( "unpack_update" );
157 oslFileHandle hOut = NULL;
158 oslProcess hProcess = NULL;
160 rtl::OUString aSystemPath;
161 osl::File::getSystemPathFromFileURL(aFile, aSystemPath);
163 oslProcessError rc = osl_executeProcess_WithRedirectedIO(
164 aUnpackPath.pData, // [in] Image name
165 &aSystemPath.pData, 1, // [in] Arguments
166 osl_Process_WAIT || osl_Process_NORMAL, // [in] Options
167 NULL, // [in] Security
168 NULL, // [in] Working directory
169 NULL, 0, // [in] Environment variables
170 &hProcess, // [out] Process handle
171 NULL, &hOut, NULL // [out] File handles for redirected I/O
174 if( osl_Process_E_None == rc )
176 oslProcessInfo aInfo;
177 aInfo.Size = sizeof(oslProcessInfo);
179 if( osl_Process_E_None == osl_getProcessInfo(hProcess, osl_Process_EXITCODE, &aInfo) )
181 if( 0 == aInfo.Code )
183 sal_Char szBuffer[4096];
184 sal_uInt64 nBytesRead = 0;
185 const sal_uInt64 nBytesToRead = sizeof(szBuffer) - 1;
187 rtl::OUString aImageName;
188 while( osl_File_E_None == osl_readFile(hOut, szBuffer, nBytesToRead, &nBytesRead) )
190 sal_Char *pc = szBuffer + nBytesRead;
193 *pc = '\0'; --pc;
195 while( ('\n' == *pc) || ('\r' == *pc) );
197 aImageName += rtl::OUString(szBuffer, pc - szBuffer + 1, osl_getThreadTextEncoding());
199 if( nBytesRead < nBytesToRead )
200 break;
203 if( osl::FileBase::E_None == osl::FileBase::getFileURLFromSystemPath(aImageName, aImageName) )
204 return aImageName;
208 osl_closeFile(hOut);
209 osl_freeProcessHandle(hProcess);
212 #endif
214 return aFile;
218 //------------------------------------------------------------------------------
220 static uno::Reference< beans::XPropertySet > createMenuBarUI(
221 const uno::Reference< uno::XComponentContext >& xContext,
222 const uno::Reference< task::XJob >& xJob)
224 if( !xContext.is() )
225 throw uno::RuntimeException(
226 UNISTRING( "UpdateCheckJob: empty component context" ), uno::Reference< uno::XInterface > () );
228 uno::Reference< lang::XMultiComponentFactory > xServiceManager(xContext->getServiceManager());
229 if( !xServiceManager.is() )
230 throw uno::RuntimeException(
231 UNISTRING( "UpdateCheckJob: unable to obtain service manager from component context" ), uno::Reference< uno::XInterface > () );
233 uno::Reference< beans::XPropertySet > xMenuBarUI =
234 uno::Reference< beans::XPropertySet > (
235 xServiceManager->createInstanceWithContext( UNISTRING( "com.sun.star.setup.UpdateCheckUI" ), xContext ),
236 uno::UNO_QUERY_THROW);
238 xMenuBarUI->setPropertyValue( PROPERTY_CLICK_HDL, uno::makeAny( xJob ) );
240 return xMenuBarUI;
243 //------------------------------------------------------------------------------
247 typedef sal_Bool (* OnlineCheckFunc) ();
249 class UpdateCheckThread : public WorkerThread
252 public:
253 UpdateCheckThread( osl::Condition& rCondition,
254 const uno::Reference<uno::XComponentContext>& xContext );
256 virtual void SAL_CALL join();
257 virtual void SAL_CALL terminate();
258 virtual void SAL_CALL cancel();
260 protected:
261 virtual ~UpdateCheckThread();
263 virtual void SAL_CALL run();
264 virtual void SAL_CALL onTerminated();
266 /* Wrapper around checkForUpdates */
267 bool runCheck();
269 private:
271 /* Used to avoid dialup login windows (on platforms we know how to double this) */
272 inline bool hasInternetConnection() const
274 if(m_pHasInternetConnection != NULL )
275 return (sal_True == m_pHasInternetConnection());
276 return true;
279 /* Creates a new instance of UpdateInformationProvider and returns this instance */
280 inline uno::Reference<deployment::XUpdateInformationProvider> createProvider()
282 osl::MutexGuard aGuard(m_aMutex);
283 m_xProvider = deployment::UpdateInformationProvider::create(m_xContext);
284 return m_xProvider;
287 /* Returns the remembered instance of UpdateInformationProvider if any */
288 inline uno::Reference<deployment::XUpdateInformationProvider> getProvider()
289 { osl::MutexGuard aGuard(m_aMutex); return m_xProvider; };
291 /* Releases the remembered instance of UpdateInformationProvider if any */
292 inline void clearProvider()
293 { osl::MutexGuard aGuard(m_aMutex); m_xProvider.clear(); };
295 osl::Mutex m_aMutex;
296 osl::Module m_aModule;
298 protected:
299 osl::Condition& m_aCondition;
301 private:
303 // const
304 OnlineCheckFunc m_pHasInternetConnection;
306 const uno::Reference<uno::XComponentContext> m_xContext;
307 uno::Reference<deployment::XUpdateInformationProvider> m_xProvider;
311 class ManualUpdateCheckThread : public UpdateCheckThread
313 public:
314 ManualUpdateCheckThread( osl::Condition& rCondition, const uno::Reference<uno::XComponentContext>& xContext ) :
315 UpdateCheckThread(rCondition, xContext) {};
317 virtual void SAL_CALL run();
321 class MenuBarButtonJob : public ::cppu::WeakImplHelper1< task::XJob >
323 public:
324 MenuBarButtonJob(const rtl::Reference< UpdateCheck >& rUpdateCheck);
326 // XJob
327 virtual uno::Any SAL_CALL execute(const uno::Sequence<beans::NamedValue>&)
328 throw (lang::IllegalArgumentException, uno::Exception);
330 private:
331 rtl::Reference< UpdateCheck > m_aUpdateCheck;
334 class DownloadThread : public WorkerThread
336 public:
337 DownloadThread(
338 osl::Condition& rCondition,
339 const uno::Reference<uno::XComponentContext>& xContext,
340 const rtl::Reference< DownloadInteractionHandler >& rHandler,
341 const rtl::OUString& rURL );
343 virtual void SAL_CALL run();
344 virtual void SAL_CALL cancel();
345 virtual void SAL_CALL suspend();
346 virtual void SAL_CALL onTerminated();
348 protected:
349 ~DownloadThread();
351 private:
352 osl::Condition& m_aCondition;
353 const uno::Reference<uno::XComponentContext> m_xContext;
354 const rtl::OUString m_aURL;
355 Download m_aDownload;
358 //------------------------------------------------------------------------------
359 class ShutdownThread : public osl::Thread
361 public:
362 ShutdownThread( const uno::Reference<uno::XComponentContext>& xContext );
364 virtual void SAL_CALL run();
365 virtual void SAL_CALL onTerminated();
367 protected:
368 ~ShutdownThread();
370 private:
371 osl::Condition m_aCondition;
372 const uno::Reference<uno::XComponentContext> m_xContext;
375 //------------------------------------------------------------------------------
377 UpdateCheckThread::UpdateCheckThread( osl::Condition& rCondition,
378 const uno::Reference<uno::XComponentContext>& xContext ) :
379 m_aCondition(rCondition),
380 m_pHasInternetConnection(NULL),
381 m_xContext(xContext)
384 #ifdef WNT
385 rtl::OUString aPath;
386 if( osl_getExecutableFile(&aPath.pData) == osl_Process_E_None )
388 sal_uInt32 lastIndex = aPath.lastIndexOf('/');
389 if ( lastIndex > 0 )
391 aPath = aPath.copy( 0, lastIndex+1 );
392 aPath += UNISTRING( "onlinecheck" );
395 if ( m_aModule.load(aPath) )
397 m_pHasInternetConnection =
398 reinterpret_cast < OnlineCheckFunc > (
399 m_aModule.getFunctionSymbol( UNISTRING("hasInternetConnection")));
402 #endif
404 createSuspended();
406 // actually run the thread
407 resume();
410 //------------------------------------------------------------------------------
412 UpdateCheckThread::~UpdateCheckThread()
416 //------------------------------------------------------------------------------
419 void SAL_CALL
420 UpdateCheckThread::terminate()
422 // Cancel potentially hanging http request ..
423 cancel();
424 // .. before terminating
425 osl::Thread::terminate();
428 //------------------------------------------------------------------------------
430 void SAL_CALL
431 UpdateCheckThread::join()
433 uno::Reference< deployment::XUpdateInformationProvider > xProvider(getProvider());
435 // do not join during an update check until #i73893# is fixed
436 if( ! xProvider.is() )
438 osl::Thread::join();
442 //------------------------------------------------------------------------------
444 void SAL_CALL
445 UpdateCheckThread::cancel()
447 uno::Reference< deployment::XUpdateInformationProvider > xProvider(getProvider());
449 if( xProvider.is() )
450 xProvider->cancel();
453 //------------------------------------------------------------------------------
455 bool
456 UpdateCheckThread::runCheck()
458 bool ret = false;
459 UpdateState eUIState = UPDATESTATE_NO_UPDATE_AVAIL;
461 UpdateInfo aInfo;
462 rtl::Reference< UpdateCheck > aController(UpdateCheck::get());
464 if( checkForUpdates(aInfo, m_xContext, aController->getInteractionHandler(), createProvider()) )
466 aController->setUpdateInfo(aInfo);
467 eUIState = aController->getUIState(aInfo);
468 ret = true;
470 else
471 aController->setCheckFailedState();
473 // We will only look for extension updates, when there is no 'check for office updates' dialog open
474 // and when there was no office update found
475 if ( ( eUIState != UPDATESTATE_UPDATE_AVAIL ) &&
476 ( eUIState != UPDATESTATE_UPDATE_NO_DOWNLOAD ) &&
477 !aController->isDialogShowing() )
479 bool bHasExtensionUpdates = checkForExtensionUpdates( m_xContext );
480 aController->setHasExtensionUpdates( bHasExtensionUpdates );
481 if ( bHasExtensionUpdates )
482 aController->setUIState( UPDATESTATE_EXT_UPD_AVAIL );
485 // joining with this thread is safe again
486 clearProvider();
487 return ret;
490 //------------------------------------------------------------------------------
492 void SAL_CALL
493 UpdateCheckThread::onTerminated()
495 delete this;
498 //------------------------------------------------------------------------------
500 void SAL_CALL
501 UpdateCheckThread::run()
503 osl::Condition::Result aResult = osl::Condition::result_timeout;
504 TimeValue tv = { 10, 0 };
506 // Initial wait to avoid doing further time consuming tasks during start-up
507 aResult = m_aCondition.wait(&tv);
509 try {
511 while( sal_True == schedule() )
513 /* Use cases:
514 * a) manual check requested from auto check thread - "last check" should not be checked (one time)
515 * a1) manual check was requested in the middle of a running auto check,
516 * condition is set
517 * a2) manual check was requested while waiting for a retry,
518 * condition is set
519 * a3) manual check was requested while waiting for time to next
520 * scheduled check elapsing, condition is set
521 * a4) manual check was requested during initial wait, condition is set
522 * b) check interval got changed, condition may be set - same sub-cases as a),
523 * but "last check" should be honored
524 * c) normal auto check mode, condition not set - "last check" should be honored
527 // Accessing const members without synchronization
528 rtl::Reference< UpdateCheck > aController(UpdateCheck::get());
529 rtl::Reference< UpdateCheckConfig > rModel = UpdateCheckConfig::get(m_xContext, *aController);
531 // FIXME: remember last & offset ?
532 sal_Int64 last = rModel->getLastChecked();
533 sal_Int64 offset = rModel->getCheckInterval();
535 rModel.clear();
537 // last == 0 means check immediately
538 bool checkNow = ! (last > 0);
540 // Reset the condition to avoid busy loops
541 if( osl::Condition::result_ok == aResult )
543 m_aCondition.reset();
544 aResult = osl::Condition::result_timeout;
545 checkNow = aController->isDialogShowing();
548 if( ! checkNow )
550 TimeValue systime;
551 osl_getSystemTime(&systime);
553 // Go back to sleep until time has elapsed
554 sal_Int64 next = last + offset;
555 if( last + offset > systime.Seconds )
557 // This can not be > 32 Bit for now ..
558 tv.Seconds = static_cast< sal_Int32 > (next - systime.Seconds);
559 aResult = m_aCondition.wait(&tv);
560 continue;
564 static sal_uInt8 n = 0;
566 if( ! hasInternetConnection() || ! runCheck() )
568 // Increase next by 1, 5, 15, 60, .. minutes
569 static const sal_Int16 nRetryInterval[] = { 60, 300, 900, 3600 };
571 if( n < sizeof(nRetryInterval) / sizeof(sal_Int16) )
572 ++n;
574 tv.Seconds = nRetryInterval[n-1];
575 aResult = m_aCondition.wait(&tv);
577 else // reset retry counter
578 n = 0;
582 catch(const uno::Exception& e) {
583 // Silently catch all errors
584 OSL_TRACE( "Caught exception: %s\n thread terminated.\n",
585 rtl::OUStringToOString(e.Message, RTL_TEXTENCODING_UTF8).getStr() );
589 //------------------------------------------------------------------------------
591 void SAL_CALL
592 ManualUpdateCheckThread::run()
594 try {
595 runCheck();
596 m_aCondition.reset();
598 catch(const uno::Exception& e) {
599 // Silently catch all errors
600 OSL_TRACE( "Caught exception: %s\n thread terminated.\n",
601 rtl::OUStringToOString(e.Message, RTL_TEXTENCODING_UTF8).getStr() );
605 //------------------------------------------------------------------------------
607 MenuBarButtonJob::MenuBarButtonJob(const rtl::Reference< UpdateCheck >& rUpdateCheck) :
608 m_aUpdateCheck(rUpdateCheck)
612 //------------------------------------------------------------------------------
614 uno::Any SAL_CALL
615 MenuBarButtonJob::execute(const uno::Sequence<beans::NamedValue>& )
616 throw (lang::IllegalArgumentException, uno::Exception)
618 if ( m_aUpdateCheck->shouldShowExtUpdDlg() )
619 m_aUpdateCheck->showExtensionDialog();
620 else
621 m_aUpdateCheck->showDialog();
623 return uno::Any();
626 //------------------------------------------------------------------------------
628 DownloadThread::DownloadThread(osl::Condition& rCondition,
629 const uno::Reference<uno::XComponentContext>& xContext,
630 const rtl::Reference< DownloadInteractionHandler >& rHandler,
631 const rtl::OUString& rURL) :
632 m_aCondition(rCondition),
633 m_xContext(xContext),
634 m_aURL(rURL),
635 m_aDownload(xContext, rHandler)
637 createSuspended();
640 //------------------------------------------------------------------------------
642 DownloadThread::~DownloadThread()
646 //------------------------------------------------------------------------------
648 void SAL_CALL
649 DownloadThread::run()
651 #ifdef WNT
652 CoUninitialize();
653 CoInitialize( NULL );
654 #endif
656 while( schedule() )
658 rtl::Reference< UpdateCheckConfig > rModel = UpdateCheckConfig::get(m_xContext);
660 rtl::OUString aLocalFile = rModel->getLocalFileName();
661 rtl::OUString aDownloadDest = rModel->getDownloadDestination();
663 // release config class for now
664 rModel.clear();
666 static sal_uInt8 n = 0;
667 if( ! m_aDownload.start(m_aURL, aLocalFile, aDownloadDest ) )
669 // retry every 15s unless the dialog is not visible
670 TimeValue tv;
671 tv.Seconds = 15;
673 if( ! UpdateCheck::get()->isDialogShowing() )
675 // Increase next by 1, 5, 15, 60, .. minutes
676 static const sal_Int16 nRetryInterval[] = { 60, 300, 900, 3600 };
678 if( n < sizeof(nRetryInterval) / sizeof(sal_Int16) )
679 ++n;
681 tv.Seconds = nRetryInterval[n-1];
683 m_aCondition.wait(&tv);
685 else
687 // reset wait period after successful download
688 n=0;
693 //------------------------------------------------------------------------------
695 void SAL_CALL DownloadThread::cancel()
697 m_aDownload.stop();
698 resume();
700 rtl::Reference< UpdateCheck > aController(UpdateCheck::get());
701 aController->cancelDownload();
704 //------------------------------------------------------------------------------
706 void SAL_CALL DownloadThread::suspend()
708 osl::Thread::suspend();
709 m_aDownload.stop();
712 //------------------------------------------------------------------------------
714 void SAL_CALL DownloadThread::onTerminated()
716 delete this;
719 //------------------------------------------------------------------------------
720 ShutdownThread::ShutdownThread( const uno::Reference<uno::XComponentContext>& xContext) :
721 m_xContext( xContext )
723 create();
726 //------------------------------------------------------------------------------
727 ShutdownThread::~ShutdownThread()
731 //------------------------------------------------------------------------------
732 void SAL_CALL
733 ShutdownThread::run()
735 TimeValue tv = { 0, 250 };
737 m_aCondition.wait(&tv);
739 // Tell QuickStarter not to veto ..
740 uno::Reference< beans::XFastPropertySet > xQuickStarter(
741 UpdateCheck::createService(UNISTRING("com.sun.star.office.Quickstart"), m_xContext),
742 uno::UNO_QUERY
745 if (xQuickStarter.is())
746 xQuickStarter->setFastPropertyValue(0, uno::makeAny(false));
748 // Shutdown the office
749 uno::Reference< frame::XDesktop > xDesktop(
750 UpdateCheck::createService(UNISTRING("com.sun.star.frame.Desktop"), m_xContext),
751 uno::UNO_QUERY);
753 if( xDesktop.is() )
754 xDesktop->terminate();
757 //------------------------------------------------------------------------------
758 void SAL_CALL ShutdownThread::onTerminated()
760 delete this;
763 //------------------------------------------------------------------------------
765 } // anonymous namespace
768 //------------------------------------------------------------------------------
771 void
772 UpdateCheck::initialize(const uno::Sequence< beans::NamedValue >& rValues,
773 const uno::Reference<uno::XComponentContext>& xContext)
775 osl::MutexGuard aGuard(m_aMutex);
777 if( NOT_INITIALIZED == m_eState )
779 NamedValueByNameAccess aNameAccess(rValues);
780 UpdateCheckROModel aModel( aNameAccess );
781 m_xContext = xContext;
783 rtl::OUString aUpdateEntryVersion = aModel.getUpdateEntryVersion();
785 aModel.getUpdateEntry(m_aUpdateInfo);
787 bool obsoleteUpdateInfo = isObsoleteUpdateInfo(aUpdateEntryVersion);
789 m_bHasExtensionUpdate = checkForPendingUpdates( xContext );
790 m_bShowExtUpdDlg = false;
792 rtl::OUString aLocalFileName = aModel.getLocalFileName();
794 if( aLocalFileName.getLength() > 0 )
796 bool downloadPaused = aModel.isDownloadPaused();
798 enableDownload(true, downloadPaused);
799 setUIState(downloadPaused ? UPDATESTATE_DOWNLOAD_PAUSED : UPDATESTATE_DOWNLOADING);
801 // Try to get the number of bytes already on disk
802 osl::DirectoryItem aDirectoryItem;
803 if( osl::DirectoryItem::E_None == osl::DirectoryItem::get(aLocalFileName, aDirectoryItem) )
805 osl::FileStatus aFileStatus(FileStatusMask_FileSize);
806 if( osl::DirectoryItem::E_None == aDirectoryItem.getFileStatus(aFileStatus) )
808 // Calculate initial percent value.
809 if( aModel.getDownloadSize() > 0 )
811 sal_Int32 nPercent = (sal_Int32) (100 * aFileStatus.getFileSize() / aModel.getDownloadSize());
812 getUpdateHandler()->setProgress(nPercent);
817 else
819 // We do this intentionally only if no download is in progress ..
820 if( obsoleteUpdateInfo )
822 // Bring-up release note for position 5 ..
823 const rtl::OUString aURL(getReleaseNote(m_aUpdateInfo, 5));
824 if( aURL.getLength() > 0 )
825 showReleaseNote(aURL);
827 // Data is outdated, probably due to installed update
828 rtl::Reference< UpdateCheckConfig > aConfig = UpdateCheckConfig::get( xContext, *this );
829 aConfig->clearUpdateFound();
831 m_aUpdateInfo = UpdateInfo();
833 else
835 enableAutoCheck(aModel.isAutoCheckEnabled());
836 setUIState(getUIState(m_aUpdateInfo));
842 //------------------------------------------------------------------------------
844 void
845 UpdateCheck::cancel()
847 osl::ClearableMutexGuard aGuard(m_aMutex);
849 WorkerThread *pThread = m_pThread;
850 UpdateState eUIState = getUIState(m_aUpdateInfo);
852 aGuard.clear();
854 if( NULL != pThread )
855 pThread->cancel();
857 setUIState(eUIState);
860 //------------------------------------------------------------------------------
862 void
863 UpdateCheck::download()
865 osl::ClearableMutexGuard aGuard(m_aMutex);
866 UpdateInfo aInfo(m_aUpdateInfo);
867 State eState = m_eState;
868 aGuard.clear();
870 if( aInfo.Sources[0].IsDirect )
872 // Ignore second click of a double click
873 if( DOWNLOADING != eState )
875 shutdownThread(true);
877 osl::ClearableMutexGuard aGuard2(m_aMutex);
878 enableDownload(true);
879 aGuard2.clear();
880 setUIState(UPDATESTATE_DOWNLOADING);
883 else
885 showReleaseNote(aInfo.Sources[0].URL); // Display in browser
889 //------------------------------------------------------------------------------
891 void
892 UpdateCheck::install()
894 osl::MutexGuard aGuard(m_aMutex);
896 const uno::Reference< c3s::XSystemShellExecute > xShellExecute(
897 createService( UNISTRING( "com.sun.star.system.SystemShellExecute" ), m_xContext ),
898 uno::UNO_QUERY );
900 try {
901 // Construct install command ??
903 // Store release note for position 3 and 4
904 rtl::OUString aURL(getReleaseNote(m_aUpdateInfo, 3));
905 storeReleaseNote(1, aURL);
907 aURL = getReleaseNote(m_aUpdateInfo, 4);
908 storeReleaseNote(2, aURL);
910 if( xShellExecute.is() )
912 rtl::OUString aInstallImage(m_aImageName);
913 osl::FileBase::getSystemPathFromFileURL(aInstallImage, aInstallImage);
915 rtl::OUString aParameter;
916 sal_Int32 nFlags = c3s::SystemShellExecuteFlags::DEFAULTS;
917 #if ( defined LINUX || defined SOLARIS )
918 nFlags = 42;
919 aParameter = getBaseInstallation();
920 if( aParameter.getLength() > 0 )
921 osl::FileBase::getSystemPathFromFileURL(aParameter, aParameter);
923 aParameter += UNISTRING(" &");
924 #endif
925 xShellExecute->execute(aInstallImage, aParameter, nFlags);
926 ShutdownThread *pShutdownThread = new ShutdownThread( m_xContext );
927 (void) pShutdownThread;
929 } catch(uno::Exception&) {
930 m_aUpdateHandler->setErrorMessage( m_aUpdateHandler->getDefaultInstErrMsg() );
934 //------------------------------------------------------------------------------
936 void
937 UpdateCheck::pause()
939 osl::ClearableMutexGuard aGuard(m_aMutex);
941 if( NULL != m_pThread )
942 m_pThread->suspend();
944 rtl::Reference< UpdateCheckConfig > rModel = UpdateCheckConfig::get(m_xContext);
945 aGuard.clear();
947 rModel->storeDownloadPaused(true);
948 setUIState(UPDATESTATE_DOWNLOAD_PAUSED);
951 //------------------------------------------------------------------------------
953 void
954 UpdateCheck::resume()
956 osl::ClearableMutexGuard aGuard(m_aMutex);
958 if( NULL != m_pThread )
959 m_pThread->resume();
961 rtl::Reference< UpdateCheckConfig > rModel = UpdateCheckConfig::get(m_xContext);
962 aGuard.clear();
964 rModel->storeDownloadPaused(false);
965 setUIState(UPDATESTATE_DOWNLOADING);
968 //------------------------------------------------------------------------------
970 void
971 UpdateCheck::closeAfterFailure()
973 osl::ClearableMutexGuard aGuard(m_aMutex);
975 if ( ( m_eState == DISABLED ) || ( m_eState == CHECK_SCHEDULED ) )
977 const UpdateState eUIState = getUIState( m_aUpdateInfo );
978 aGuard.clear();
979 setUIState( eUIState, true );
983 //------------------------------------------------------------------------------
985 void
986 UpdateCheck::shutdownThread(bool join)
988 osl::ClearableMutexGuard aGuard(m_aMutex);
990 // copy thread object pointer to stack
991 osl::Thread *pThread = m_pThread;
992 m_pThread = NULL;
993 aGuard.clear();
995 if( NULL != pThread )
997 pThread->terminate();
998 if( join )
1000 m_aCondition.set();
1001 pThread->join();
1002 m_aCondition.reset();
1007 //------------------------------------------------------------------------------
1009 void
1010 UpdateCheck::enableAutoCheck(bool enable)
1012 if( enable )
1013 m_pThread = new UpdateCheckThread(m_aCondition, m_xContext);
1015 m_eState = enable ? CHECK_SCHEDULED : DISABLED;
1018 //------------------------------------------------------------------------------
1020 void
1021 UpdateCheck::enableDownload(bool enable, bool paused)
1023 OSL_ASSERT(NULL == m_pThread);
1025 State eState = DISABLED;
1026 if( enable )
1028 m_pThread = new DownloadThread(m_aCondition, m_xContext, this, m_aUpdateInfo.Sources[0].URL );
1029 if( !paused )
1031 eState = DOWNLOADING;
1032 m_pThread->resume();
1034 else
1035 eState = DOWNLOAD_PAUSED;
1037 m_eState = eState;
1039 else {
1040 enableAutoCheck(UpdateCheckConfig::get(m_xContext)->isAutoCheckEnabled());
1045 //------------------------------------------------------------------------------
1047 bool
1048 UpdateCheck::downloadTargetExists(const rtl::OUString& rFileName)
1050 osl::ClearableMutexGuard aGuard(m_aMutex);
1052 rtl::Reference< UpdateHandler > aUpdateHandler(getUpdateHandler());
1053 UpdateState eUIState = UPDATESTATE_DOWNLOADING;
1055 bool cont = false;
1057 if( aUpdateHandler->isVisible() )
1059 cont = aUpdateHandler->showOverwriteWarning();
1060 if( cont )
1062 if( osl_File_E_None != osl_removeFile(rFileName.pData) )
1064 // FIXME: error message
1065 cont = false;
1068 else
1069 eUIState = getUIState(m_aUpdateInfo);
1071 else
1073 m_aImageName = getImageFromFileName(rFileName);
1074 eUIState = UPDATESTATE_DOWNLOAD_AVAIL;
1077 if( !cont )
1079 shutdownThread(false);
1080 enableDownload(false);
1082 aGuard.clear();
1083 setUIState(eUIState);
1086 return cont;
1089 //------------------------------------------------------------------------------
1091 void
1092 UpdateCheck::downloadStalled(const rtl::OUString& rErrorMessage)
1094 osl::ClearableMutexGuard aGuard(m_aMutex);
1095 rtl::Reference< UpdateHandler > aUpdateHandler(getUpdateHandler());
1096 aGuard.clear();
1098 aUpdateHandler->setErrorMessage(rErrorMessage);
1099 setUIState(UPDATESTATE_ERROR_DOWNLOADING);
1102 //------------------------------------------------------------------------------
1104 void
1105 UpdateCheck::downloadProgressAt(sal_Int8 nPercent)
1107 osl::ClearableMutexGuard aGuard(m_aMutex);
1108 rtl::Reference< UpdateHandler > aUpdateHandler(getUpdateHandler());
1109 aGuard.clear();
1111 aUpdateHandler->setProgress(nPercent);
1112 setUIState(UPDATESTATE_DOWNLOADING);
1115 //------------------------------------------------------------------------------
1117 void
1118 UpdateCheck::downloadStarted(const rtl::OUString& rLocalFileName, sal_Int64 nFileSize)
1120 osl::MutexGuard aGuard(m_aMutex);
1122 rtl::Reference< UpdateCheckConfig > aModel(UpdateCheckConfig::get(m_xContext));
1123 aModel->storeLocalFileName(rLocalFileName, nFileSize);
1125 // Bring-up release note for position 1 ..
1126 const rtl::OUString aURL(getReleaseNote(m_aUpdateInfo, 1, aModel->isAutoDownloadEnabled()));
1127 if( aURL.getLength() > 0 )
1128 showReleaseNote(aURL);
1131 //------------------------------------------------------------------------------
1133 void
1134 UpdateCheck::downloadFinished(const rtl::OUString& rLocalFileName)
1136 osl::ClearableMutexGuard aGuard(m_aMutex);
1138 // no more retries
1139 m_pThread->terminate();
1141 rtl::Reference< UpdateCheckConfig > rModel = UpdateCheckConfig::get(m_xContext);
1142 rModel->clearLocalFileName();
1144 m_aImageName = getImageFromFileName(rLocalFileName);
1145 UpdateInfo aUpdateInfo(m_aUpdateInfo);
1147 aGuard.clear();
1148 setUIState(UPDATESTATE_DOWNLOAD_AVAIL);
1150 // Bring-up release note for position 2 ..
1151 const rtl::OUString aURL(getReleaseNote(aUpdateInfo, 2, rModel->isAutoDownloadEnabled()));
1152 if( aURL.getLength() > 0 )
1153 showReleaseNote(aURL);
1156 //------------------------------------------------------------------------------
1158 void
1159 UpdateCheck::cancelDownload()
1161 shutdownThread(true);
1163 osl::MutexGuard aGuard(m_aMutex);
1164 enableDownload(false);
1166 rtl::Reference< UpdateCheckConfig > rModel = UpdateCheckConfig::get(m_xContext);
1168 rtl::OUString aLocalFile(rModel->getLocalFileName());
1169 rModel->clearLocalFileName();
1170 rModel->storeDownloadPaused(false);
1172 if( isObsoleteUpdateInfo(rModel->getUpdateEntryVersion()) )
1174 rModel->clearUpdateFound(); // This wasn't done during init yet ..
1175 m_aUpdateInfo = UpdateInfo();
1178 /*oslFileError rc =*/ osl_removeFile(aLocalFile.pData);
1179 // FIXME: error handling ..
1183 //------------------------------------------------------------------------------
1185 void
1186 UpdateCheck::showDialog(bool forceCheck)
1188 osl::ResettableMutexGuard aGuard(m_aMutex);
1190 bool update_found = m_aUpdateInfo.BuildId.getLength() > 0;
1191 bool bSetUIState = ! m_aUpdateHandler.is();
1193 UpdateState eDialogState = UPDATESTATES_COUNT;
1195 switch( m_eState )
1197 case DISABLED:
1198 case CHECK_SCHEDULED:
1199 if( forceCheck || ! update_found ) // Run check when forced or if we did not find an update yet
1201 eDialogState = UPDATESTATE_CHECKING;
1202 bSetUIState = true;
1204 else if(m_aUpdateInfo.Sources[0].IsDirect)
1205 eDialogState = UPDATESTATE_UPDATE_AVAIL;
1206 else
1207 eDialogState = UPDATESTATE_UPDATE_NO_DOWNLOAD;
1208 break;
1210 case DOWNLOADING:
1211 eDialogState = UPDATESTATE_DOWNLOADING;
1212 break;
1214 case DOWNLOAD_PAUSED:
1215 eDialogState = UPDATESTATE_DOWNLOAD_PAUSED;
1216 break;
1218 case NOT_INITIALIZED:
1219 OSL_ASSERT( false );
1220 break;
1223 if( bSetUIState )
1225 aGuard.clear();
1226 setUIState(eDialogState, true); // suppress bubble as Dialog will be visible soon
1227 aGuard.reset();
1230 getUpdateHandler()->setVisible(true);
1232 // Run check in separate thread ..
1233 if( UPDATESTATE_CHECKING == eDialogState )
1235 if( DISABLED == m_eState )
1237 // destructs itself when done, not cancellable for now ..
1238 new ManualUpdateCheckThread(m_aCondition, m_xContext);
1241 m_aCondition.set();
1245 //------------------------------------------------------------------------------
1247 void
1248 UpdateCheck::setUpdateInfo(const UpdateInfo& aInfo)
1250 osl::ClearableMutexGuard aGuard(m_aMutex);
1252 bool bSuppressBubble = (sal_True == aInfo.BuildId.equals(m_aUpdateInfo.BuildId));
1253 m_aUpdateInfo = aInfo;
1255 OSL_ASSERT(DISABLED == m_eState || CHECK_SCHEDULED == m_eState);
1257 // Ignore leading non direct download if we get direct ones
1258 std::vector< DownloadSource >::iterator iter = m_aUpdateInfo.Sources.begin();
1259 while( iter != m_aUpdateInfo.Sources.end() )
1261 if( iter->IsDirect )
1262 break;
1264 ++iter;
1267 if( (iter != m_aUpdateInfo.Sources.begin()) &&
1268 (iter != m_aUpdateInfo.Sources.end()) &&
1269 iter->IsDirect )
1271 m_aUpdateInfo.Sources.erase(m_aUpdateInfo.Sources.begin(), --iter);
1274 rtl::Reference< UpdateCheckConfig > rModel = UpdateCheckConfig::get(m_xContext, *this);
1275 OSL_ASSERT( rModel.is() );
1277 // Decide whether to use alternate release note pos ..
1278 bool autoDownloadEnabled = rModel->isAutoDownloadEnabled();
1280 std::vector< ReleaseNote >::iterator iter2 = m_aUpdateInfo.ReleaseNotes.begin();
1281 while( iter2 != m_aUpdateInfo.ReleaseNotes.end() )
1283 if( ((1 == iter2->Pos) || (2 == iter2->Pos)) && autoDownloadEnabled && (iter2->URL2.getLength() > 0))
1285 iter2->URL = iter2->URL2;
1286 iter2->URL2 = rtl::OUString();
1287 iter2->Pos = iter2->Pos2;
1288 iter2->Pos2 = 0;
1291 ++iter2;
1294 // do not move below store/clear ..
1295 rModel->updateLastChecked();
1297 UpdateState eUIState;
1298 if( m_aUpdateInfo.Sources.size() > 0 )
1300 rModel->storeUpdateFound(aInfo, getBuildId());
1302 if( m_aUpdateInfo.Sources[0].IsDirect )
1304 eUIState = UPDATESTATE_UPDATE_AVAIL;
1306 if( rModel->isAutoDownloadEnabled() )
1308 shutdownThread(false);
1309 eUIState = UPDATESTATE_DOWNLOADING;
1310 enableDownload(true);
1313 else
1314 eUIState = UPDATESTATE_UPDATE_NO_DOWNLOAD;
1316 else
1318 eUIState = UPDATESTATE_NO_UPDATE_AVAIL;
1319 rModel->clearUpdateFound();
1322 aGuard.clear();
1323 setUIState(eUIState, bSuppressBubble);
1326 //------------------------------------------------------------------------------
1328 void
1329 UpdateCheck::setCheckFailedState()
1331 setUIState(UPDATESTATE_ERROR_CHECKING);
1334 //------------------------------------------------------------------------------
1335 void UpdateCheck::handleMenuBarUI( rtl::Reference< UpdateHandler > rUpdateHandler,
1336 UpdateState& eState,
1337 bool suppressBubble )
1339 uno::Reference<beans::XPropertySet> xMenuBarUI( m_xMenuBarUI );
1341 if ( ( UPDATESTATE_NO_UPDATE_AVAIL == eState ) && m_bHasExtensionUpdate )
1342 eState = UPDATESTATE_EXT_UPD_AVAIL;
1344 if ( UPDATESTATE_EXT_UPD_AVAIL == eState )
1345 m_bShowExtUpdDlg = true;
1346 else
1347 m_bShowExtUpdDlg = false;
1349 if( xMenuBarUI.is() )
1351 if( UPDATESTATE_NO_UPDATE_AVAIL == eState )
1353 xMenuBarUI->setPropertyValue( PROPERTY_SHOW_MENUICON, uno::makeAny(sal_False) );
1355 else
1357 xMenuBarUI->setPropertyValue( PROPERTY_TITLE, uno::makeAny(rUpdateHandler->getBubbleTitle(eState)) );
1358 xMenuBarUI->setPropertyValue( PROPERTY_TEXT, uno::makeAny(rUpdateHandler->getBubbleText(eState)) );
1360 if( ! suppressBubble && ( ! rUpdateHandler->isVisible() || rUpdateHandler->isMinimized() ) )
1361 xMenuBarUI->setPropertyValue( PROPERTY_SHOW_BUBBLE, uno::makeAny( sal_True ) );
1363 if( UPDATESTATE_CHECKING != eState )
1364 xMenuBarUI->setPropertyValue( PROPERTY_SHOW_MENUICON, uno::makeAny(sal_True) );
1369 //------------------------------------------------------------------------------
1370 void UpdateCheck::setUIState(UpdateState eState, bool suppressBubble)
1372 osl::ClearableMutexGuard aGuard(m_aMutex);
1374 if( ! m_xMenuBarUI.is() &&
1375 (DISABLED != m_eState) &&
1376 ( m_bHasExtensionUpdate || (UPDATESTATE_NO_UPDATE_AVAIL != eState)) &&
1377 (UPDATESTATE_CHECKING != eState) &&
1378 (UPDATESTATE_ERROR_CHECKING != eState)
1381 m_xMenuBarUI = createMenuBarUI(m_xContext, new MenuBarButtonJob(this));
1384 // Show bubble only when the status has changed
1385 if ( eState == m_eUpdateState )
1386 suppressBubble = true;
1387 else
1388 m_eUpdateState = eState;
1390 rtl::Reference<UpdateHandler> aUpdateHandler(getUpdateHandler());
1391 OSL_ASSERT( aUpdateHandler.is() );
1393 UpdateInfo aUpdateInfo(m_aUpdateInfo);
1394 rtl::OUString aImageName(m_aImageName);
1396 aGuard.clear();
1398 handleMenuBarUI( aUpdateHandler, eState, suppressBubble );
1400 if( (UPDATESTATE_UPDATE_AVAIL == eState)
1401 || (UPDATESTATE_DOWNLOAD_PAUSED == eState)
1402 || (UPDATESTATE_DOWNLOADING == eState) )
1404 uno::Reference< uno::XComponentContext > xContext(m_xContext);
1406 rtl::OUString aDownloadDestination =
1407 UpdateCheckConfig::get(xContext, this)->getDownloadDestination();
1409 osl_getSystemPathFromFileURL(aDownloadDestination.pData, &aDownloadDestination.pData);
1411 aUpdateHandler->setDownloadPath(aDownloadDestination);
1413 else if( UPDATESTATE_DOWNLOAD_AVAIL == eState )
1415 aUpdateHandler->setDownloadFile(aImageName);
1418 aUpdateHandler->setDescription(aUpdateInfo.Description);
1419 aUpdateHandler->setNextVersion(aUpdateInfo.Version);
1420 aUpdateHandler->setState(eState);
1423 //------------------------------------------------------------------------------
1425 UpdateState
1426 UpdateCheck::getUIState(const UpdateInfo& rInfo)
1428 UpdateState eUIState = UPDATESTATE_NO_UPDATE_AVAIL;
1430 if( rInfo.BuildId.getLength() > 0 )
1432 if( rInfo.Sources[0].IsDirect )
1433 eUIState = UPDATESTATE_UPDATE_AVAIL;
1434 else
1435 eUIState = UPDATESTATE_UPDATE_NO_DOWNLOAD;
1438 return eUIState;
1441 //------------------------------------------------------------------------------
1443 void
1444 UpdateCheck::showReleaseNote(const rtl::OUString& rURL) const
1446 const uno::Reference< c3s::XSystemShellExecute > xShellExecute(
1447 createService( UNISTRING( "com.sun.star.system.SystemShellExecute" ), m_xContext ),
1448 uno::UNO_QUERY );
1450 try {
1452 if( xShellExecute.is() )
1453 xShellExecute->execute(rURL, rtl::OUString(), c3s::SystemShellExecuteFlags::DEFAULTS);
1454 } catch(c3s::SystemShellExecuteException&) {
1458 //------------------------------------------------------------------------------
1460 bool
1461 UpdateCheck::storeReleaseNote(sal_Int8 nNum, const rtl::OUString &rURL)
1463 osl::FileBase::RC rc;
1464 rtl::OUString aTargetDir( UpdateCheckConfig::getAllUsersDirectory() + UNISTRING( "/sun" ) );
1466 rc = osl::Directory::createPath( aTargetDir );
1468 rtl::OUString aFileName = UNISTRING("releasenote") +
1469 rtl::OUString::valueOf( (sal_Int32) nNum ) +
1470 UNISTRING(".url");
1472 rtl::OUString aFilePath;
1473 rc = osl::FileBase::getAbsoluteFileURL( aTargetDir, aFileName, aFilePath );
1474 if ( rc != osl::FileBase::E_None ) return false;
1476 rc = osl::File::remove( aFilePath );
1478 // don't store empty release notes, but delete old ones
1479 if ( rURL.getLength() == 0 )
1480 return true;
1482 osl::File aFile( aFilePath );
1483 rc = aFile.open( OpenFlag_Write | OpenFlag_Create );
1485 if ( rc != osl::FileBase::E_None ) return false;
1487 rtl::OString aLineBuf("[InternetShortcut]\r\n");
1488 sal_uInt64 nWritten = 0;
1490 rtl::OUString aURL( rURL );
1491 #ifdef WNT
1492 rc = aFile.write( aLineBuf.getStr(), aLineBuf.getLength(), nWritten );
1493 if ( rc != osl::FileBase::E_None ) return false;
1494 aURL = UNISTRING("URL=") + rURL;
1495 #endif
1496 aLineBuf = rtl::OUStringToOString( aURL, RTL_TEXTENCODING_UTF8 );
1497 rc = aFile.write( aLineBuf.getStr(), aLineBuf.getLength(), nWritten );
1498 if ( rc != osl::FileBase::E_None ) return false;
1500 aFile.close();
1501 return true;
1504 //------------------------------------------------------------------------------
1505 void UpdateCheck::showExtensionDialog()
1507 rtl::OUString sServiceName = UNISTRING("com.sun.star.deployment.ui.PackageManagerDialog");
1508 rtl::OUString sArguments = UNISTRING("SHOW_UPDATE_DIALOG");
1509 uno::Reference< uno::XInterface > xService;
1511 if( ! m_xContext.is() )
1512 throw uno::RuntimeException(
1513 UNISTRING( "UpdateCheck::showExtensionDialog(): empty component context" ), uno::Reference< uno::XInterface > () );
1515 uno::Reference< lang::XMultiComponentFactory > xServiceManager( m_xContext->getServiceManager() );
1516 if( !xServiceManager.is() )
1517 throw uno::RuntimeException(
1518 UNISTRING( "UpdateCheck::showExtensionDialog(): unable to obtain service manager from component context" ), uno::Reference< uno::XInterface > () );
1520 xService = xServiceManager->createInstanceWithContext( sServiceName, m_xContext );
1521 uno::Reference< task::XJobExecutor > xExecuteable( xService, uno::UNO_QUERY );
1522 if ( xExecuteable.is() )
1523 xExecuteable->trigger( sArguments );
1526 //------------------------------------------------------------------------------
1528 rtl::Reference<UpdateHandler>
1529 UpdateCheck::getUpdateHandler()
1531 if( ! m_aUpdateHandler.is() )
1532 m_aUpdateHandler = new UpdateHandler(m_xContext, this);
1534 return m_aUpdateHandler;
1537 //------------------------------------------------------------------------------
1539 uno::Reference< task::XInteractionHandler >
1540 UpdateCheck::getInteractionHandler() const
1542 osl::MutexGuard aGuard(m_aMutex);
1544 uno::Reference< task::XInteractionHandler > xHandler;
1546 if( m_aUpdateHandler.is() && m_aUpdateHandler->isVisible() )
1547 xHandler = m_aUpdateHandler.get();
1549 return xHandler;
1552 //------------------------------------------------------------------------------
1554 uno::Reference< uno::XInterface >
1555 UpdateCheck::createService(const rtl::OUString& rServiceName,
1556 const uno::Reference<uno::XComponentContext>& xContext)
1558 if( !xContext.is() )
1559 throw uno::RuntimeException(
1560 UNISTRING( "UpdateCheckConfig: empty component context" ),
1561 uno::Reference< uno::XInterface >() );
1563 const uno::Reference< lang::XMultiComponentFactory > xServiceManager(xContext->getServiceManager());
1565 if( !xServiceManager.is() )
1566 throw uno::RuntimeException(
1567 UNISTRING( "UpdateCheckConfig: unable to obtain service manager from component context" ),
1568 uno::Reference< uno::XInterface >() );
1570 return xServiceManager->createInstanceWithContext(rServiceName, xContext);
1573 //------------------------------------------------------------------------------
1575 bool
1576 UpdateCheck::isDialogShowing() const
1578 osl::MutexGuard aGuard(m_aMutex);
1579 return sal_True == m_aUpdateHandler.is() && m_aUpdateHandler->isVisible();
1582 //------------------------------------------------------------------------------
1584 void
1585 UpdateCheck::autoCheckStatusChanged(bool enabled)
1587 osl::ClearableMutexGuard aGuard(m_aMutex);
1589 if( (CHECK_SCHEDULED == m_eState) && !enabled )
1590 shutdownThread(false);
1592 if( (DISABLED == m_eState) || (CHECK_SCHEDULED == m_eState) )
1594 enableAutoCheck(enabled);
1595 UpdateState eState = getUIState(m_aUpdateInfo);
1596 aGuard.clear();
1597 setUIState(eState);
1601 //------------------------------------------------------------------------------
1603 void
1604 UpdateCheck::autoCheckIntervalChanged()
1606 // just wake-up
1607 m_aCondition.set();
1610 //------------------------------------------------------------------------------
1612 oslInterlockedCount SAL_CALL
1613 UpdateCheck::acquire() SAL_THROW(())
1615 return ReferenceObject::acquire();
1618 //------------------------------------------------------------------------------
1620 oslInterlockedCount SAL_CALL
1621 UpdateCheck::release() SAL_THROW(())
1623 return ReferenceObject::release();