1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4*cdf0e10cSrcweir * 5*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6*cdf0e10cSrcweir * 7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * This file is part of OpenOffice.org. 10*cdf0e10cSrcweir * 11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13*cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14*cdf0e10cSrcweir * 15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22*cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24*cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25*cdf0e10cSrcweir * 26*cdf0e10cSrcweir ************************************************************************/ 27*cdf0e10cSrcweir 28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 29*cdf0e10cSrcweir #include "precompiled_extensions.hxx" 30*cdf0e10cSrcweir 31*cdf0e10cSrcweir #include "updatecheck.hxx" 32*cdf0e10cSrcweir 33*cdf0e10cSrcweir #include <cppuhelper/implbase1.hxx> 34*cdf0e10cSrcweir #include <com/sun/star/beans/XFastPropertySet.hpp> 35*cdf0e10cSrcweir #include <com/sun/star/lang/XComponent.hpp> 36*cdf0e10cSrcweir #include <com/sun/star/frame/XDesktop.hpp> 37*cdf0e10cSrcweir #include <com/sun/star/frame/XFrame.hpp> 38*cdf0e10cSrcweir #include <com/sun/star/frame/DispatchResultEvent.hpp> 39*cdf0e10cSrcweir #include <com/sun/star/frame/DispatchResultState.hpp> 40*cdf0e10cSrcweir #include <com/sun/star/system/XSystemShellExecute.hpp> 41*cdf0e10cSrcweir #include <com/sun/star/system/SystemShellExecuteFlags.hpp> 42*cdf0e10cSrcweir #include <com/sun/star/task/XJob.hpp> 43*cdf0e10cSrcweir #include <com/sun/star/task/XJobExecutor.hpp> 44*cdf0e10cSrcweir 45*cdf0e10cSrcweir // #include <comphelper/processfactory.hxx> 46*cdf0e10cSrcweir 47*cdf0e10cSrcweir #include <rtl/ustrbuf.hxx> 48*cdf0e10cSrcweir 49*cdf0e10cSrcweir #include <rtl/bootstrap.hxx> 50*cdf0e10cSrcweir #include <osl/process.h> 51*cdf0e10cSrcweir #include <osl/module.hxx> 52*cdf0e10cSrcweir #include <osl/file.hxx> 53*cdf0e10cSrcweir 54*cdf0e10cSrcweir #ifdef WNT 55*cdf0e10cSrcweir #ifdef _MSC_VER 56*cdf0e10cSrcweir #pragma warning(push,1) // disable warnings within system headers 57*cdf0e10cSrcweir //#pragma warning(disable: 4917) 58*cdf0e10cSrcweir #endif 59*cdf0e10cSrcweir #include <objbase.h> 60*cdf0e10cSrcweir #ifdef _MSC_VER 61*cdf0e10cSrcweir #pragma warning(pop) 62*cdf0e10cSrcweir #endif 63*cdf0e10cSrcweir #endif 64*cdf0e10cSrcweir 65*cdf0e10cSrcweir #include "updateprotocol.hxx" 66*cdf0e10cSrcweir #include "updatecheckconfig.hxx" 67*cdf0e10cSrcweir 68*cdf0e10cSrcweir namespace awt = com::sun::star::awt ; 69*cdf0e10cSrcweir namespace beans = com::sun::star::beans ; 70*cdf0e10cSrcweir namespace container = com::sun::star::container ; 71*cdf0e10cSrcweir namespace deployment = com::sun::star::deployment ; 72*cdf0e10cSrcweir namespace frame = com::sun::star::frame ; 73*cdf0e10cSrcweir namespace lang = com::sun::star::lang ; 74*cdf0e10cSrcweir namespace c3s = com::sun::star::system ; 75*cdf0e10cSrcweir namespace task = com::sun::star::task ; 76*cdf0e10cSrcweir namespace util = com::sun::star::util ; 77*cdf0e10cSrcweir namespace uno = com::sun::star::uno ; 78*cdf0e10cSrcweir 79*cdf0e10cSrcweir #define UNISTRING(s) rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(s)) 80*cdf0e10cSrcweir 81*cdf0e10cSrcweir #define PROPERTY_TITLE UNISTRING("BubbleHeading") 82*cdf0e10cSrcweir #define PROPERTY_TEXT UNISTRING("BubbleText") 83*cdf0e10cSrcweir #define PROPERTY_IMAGE UNISTRING("BubbleImageURL") 84*cdf0e10cSrcweir #define PROPERTY_SHOW_BUBBLE UNISTRING("BubbleVisible") 85*cdf0e10cSrcweir #define PROPERTY_CLICK_HDL UNISTRING("MenuClickHDL") 86*cdf0e10cSrcweir #define PROPERTY_DEFAULT_TITLE UNISTRING("DefaultHeading") 87*cdf0e10cSrcweir #define PROPERTY_DEFAULT_TEXT UNISTRING("DefaultText") 88*cdf0e10cSrcweir #define PROPERTY_SHOW_MENUICON UNISTRING("MenuIconVisible") 89*cdf0e10cSrcweir 90*cdf0e10cSrcweir //------------------------------------------------------------------------------ 91*cdf0e10cSrcweir 92*cdf0e10cSrcweir // Returns the URL of the release note for the given position 93*cdf0e10cSrcweir rtl::OUString getReleaseNote(const UpdateInfo& rInfo, sal_uInt8 pos, bool autoDownloadEnabled) 94*cdf0e10cSrcweir { 95*cdf0e10cSrcweir std::vector< ReleaseNote >::const_iterator iter = rInfo.ReleaseNotes.begin(); 96*cdf0e10cSrcweir while( iter != rInfo.ReleaseNotes.end() ) 97*cdf0e10cSrcweir { 98*cdf0e10cSrcweir if( pos == iter->Pos ) 99*cdf0e10cSrcweir { 100*cdf0e10cSrcweir if( (pos > 2) || !autoDownloadEnabled || ! (iter->URL2.getLength() > 0) ) 101*cdf0e10cSrcweir return iter->URL; 102*cdf0e10cSrcweir } 103*cdf0e10cSrcweir else if( (pos == iter->Pos2) && ((1 == iter->Pos) || (2 == iter->Pos)) && autoDownloadEnabled ) 104*cdf0e10cSrcweir return iter->URL2; 105*cdf0e10cSrcweir 106*cdf0e10cSrcweir ++iter; 107*cdf0e10cSrcweir } 108*cdf0e10cSrcweir 109*cdf0e10cSrcweir return rtl::OUString(); 110*cdf0e10cSrcweir } 111*cdf0e10cSrcweir 112*cdf0e10cSrcweir //------------------------------------------------------------------------------ 113*cdf0e10cSrcweir 114*cdf0e10cSrcweir namespace 115*cdf0e10cSrcweir { 116*cdf0e10cSrcweir 117*cdf0e10cSrcweir static inline rtl::OUString getBuildId() 118*cdf0e10cSrcweir { 119*cdf0e10cSrcweir rtl::OUString aPathVal(UNISTRING("${$OOO_BASE_DIR/program/" SAL_CONFIGFILE("version") ":buildid}")); 120*cdf0e10cSrcweir rtl::Bootstrap::expandMacros(aPathVal); 121*cdf0e10cSrcweir return aPathVal; 122*cdf0e10cSrcweir } 123*cdf0e10cSrcweir 124*cdf0e10cSrcweir //------------------------------------------------------------------------------ 125*cdf0e10cSrcweir static inline rtl::OUString getBaseInstallation() 126*cdf0e10cSrcweir { 127*cdf0e10cSrcweir rtl::OUString aPathVal(UNISTRING("${$BRAND_BASE_DIR/program/" SAL_CONFIGFILE("bootstrap") ":BaseInstallation}")); 128*cdf0e10cSrcweir rtl::Bootstrap::expandMacros(aPathVal); 129*cdf0e10cSrcweir return aPathVal; 130*cdf0e10cSrcweir } 131*cdf0e10cSrcweir 132*cdf0e10cSrcweir //------------------------------------------------------------------------------ 133*cdf0e10cSrcweir 134*cdf0e10cSrcweir inline bool isObsoleteUpdateInfo(const rtl::OUString& rBuildId) 135*cdf0e10cSrcweir { 136*cdf0e10cSrcweir return sal_True != rBuildId.equals(getBuildId()) && rBuildId.getLength() > 0; 137*cdf0e10cSrcweir } 138*cdf0e10cSrcweir 139*cdf0e10cSrcweir 140*cdf0e10cSrcweir //------------------------------------------------------------------------------ 141*cdf0e10cSrcweir 142*cdf0e10cSrcweir rtl::OUString getImageFromFileName(const rtl::OUString& aFile) 143*cdf0e10cSrcweir { 144*cdf0e10cSrcweir #ifndef WNT 145*cdf0e10cSrcweir rtl::OUString aUnpackPath; 146*cdf0e10cSrcweir if( osl_getExecutableFile(&aUnpackPath.pData) == osl_Process_E_None ) 147*cdf0e10cSrcweir { 148*cdf0e10cSrcweir sal_uInt32 lastIndex = aUnpackPath.lastIndexOf('/'); 149*cdf0e10cSrcweir if ( lastIndex > 0 ) 150*cdf0e10cSrcweir { 151*cdf0e10cSrcweir aUnpackPath = aUnpackPath.copy( 0, lastIndex+1 ); 152*cdf0e10cSrcweir aUnpackPath += UNISTRING( "unpack_update" ); 153*cdf0e10cSrcweir } 154*cdf0e10cSrcweir 155*cdf0e10cSrcweir oslFileHandle hOut = NULL; 156*cdf0e10cSrcweir oslProcess hProcess = NULL; 157*cdf0e10cSrcweir 158*cdf0e10cSrcweir rtl::OUString aSystemPath; 159*cdf0e10cSrcweir osl::File::getSystemPathFromFileURL(aFile, aSystemPath); 160*cdf0e10cSrcweir 161*cdf0e10cSrcweir oslProcessError rc = osl_executeProcess_WithRedirectedIO( 162*cdf0e10cSrcweir aUnpackPath.pData, // [in] Image name 163*cdf0e10cSrcweir &aSystemPath.pData, 1, // [in] Arguments 164*cdf0e10cSrcweir osl_Process_WAIT || osl_Process_NORMAL, // [in] Options 165*cdf0e10cSrcweir NULL, // [in] Security 166*cdf0e10cSrcweir NULL, // [in] Working directory 167*cdf0e10cSrcweir NULL, 0, // [in] Environment variables 168*cdf0e10cSrcweir &hProcess, // [out] Process handle 169*cdf0e10cSrcweir NULL, &hOut, NULL // [out] File handles for redirected I/O 170*cdf0e10cSrcweir ); 171*cdf0e10cSrcweir 172*cdf0e10cSrcweir if( osl_Process_E_None == rc ) 173*cdf0e10cSrcweir { 174*cdf0e10cSrcweir oslProcessInfo aInfo; 175*cdf0e10cSrcweir aInfo.Size = sizeof(oslProcessInfo); 176*cdf0e10cSrcweir 177*cdf0e10cSrcweir if( osl_Process_E_None == osl_getProcessInfo(hProcess, osl_Process_EXITCODE, &aInfo) ) 178*cdf0e10cSrcweir { 179*cdf0e10cSrcweir if( 0 == aInfo.Code ) 180*cdf0e10cSrcweir { 181*cdf0e10cSrcweir sal_Char szBuffer[4096]; 182*cdf0e10cSrcweir sal_uInt64 nBytesRead = 0; 183*cdf0e10cSrcweir const sal_uInt64 nBytesToRead = sizeof(szBuffer) - 1; 184*cdf0e10cSrcweir 185*cdf0e10cSrcweir rtl::OUString aImageName; 186*cdf0e10cSrcweir while( osl_File_E_None == osl_readFile(hOut, szBuffer, nBytesToRead, &nBytesRead) ) 187*cdf0e10cSrcweir { 188*cdf0e10cSrcweir sal_Char *pc = szBuffer + nBytesRead; 189*cdf0e10cSrcweir do 190*cdf0e10cSrcweir { 191*cdf0e10cSrcweir *pc = '\0'; --pc; 192*cdf0e10cSrcweir } 193*cdf0e10cSrcweir while( ('\n' == *pc) || ('\r' == *pc) ); 194*cdf0e10cSrcweir 195*cdf0e10cSrcweir aImageName += rtl::OUString(szBuffer, pc - szBuffer + 1, osl_getThreadTextEncoding()); 196*cdf0e10cSrcweir 197*cdf0e10cSrcweir if( nBytesRead < nBytesToRead ) 198*cdf0e10cSrcweir break; 199*cdf0e10cSrcweir } 200*cdf0e10cSrcweir 201*cdf0e10cSrcweir if( osl::FileBase::E_None == osl::FileBase::getFileURLFromSystemPath(aImageName, aImageName) ) 202*cdf0e10cSrcweir return aImageName; 203*cdf0e10cSrcweir } 204*cdf0e10cSrcweir } 205*cdf0e10cSrcweir 206*cdf0e10cSrcweir osl_closeFile(hOut); 207*cdf0e10cSrcweir osl_freeProcessHandle(hProcess); 208*cdf0e10cSrcweir } 209*cdf0e10cSrcweir } 210*cdf0e10cSrcweir #endif 211*cdf0e10cSrcweir 212*cdf0e10cSrcweir return aFile; 213*cdf0e10cSrcweir } 214*cdf0e10cSrcweir 215*cdf0e10cSrcweir 216*cdf0e10cSrcweir //------------------------------------------------------------------------------ 217*cdf0e10cSrcweir 218*cdf0e10cSrcweir static uno::Reference< beans::XPropertySet > createMenuBarUI( 219*cdf0e10cSrcweir const uno::Reference< uno::XComponentContext >& xContext, 220*cdf0e10cSrcweir const uno::Reference< task::XJob >& xJob) 221*cdf0e10cSrcweir { 222*cdf0e10cSrcweir if( !xContext.is() ) 223*cdf0e10cSrcweir throw uno::RuntimeException( 224*cdf0e10cSrcweir UNISTRING( "UpdateCheckJob: empty component context" ), uno::Reference< uno::XInterface > () ); 225*cdf0e10cSrcweir 226*cdf0e10cSrcweir uno::Reference< lang::XMultiComponentFactory > xServiceManager(xContext->getServiceManager()); 227*cdf0e10cSrcweir if( !xServiceManager.is() ) 228*cdf0e10cSrcweir throw uno::RuntimeException( 229*cdf0e10cSrcweir UNISTRING( "UpdateCheckJob: unable to obtain service manager from component context" ), uno::Reference< uno::XInterface > () ); 230*cdf0e10cSrcweir 231*cdf0e10cSrcweir uno::Reference< beans::XPropertySet > xMenuBarUI = 232*cdf0e10cSrcweir uno::Reference< beans::XPropertySet > ( 233*cdf0e10cSrcweir xServiceManager->createInstanceWithContext( UNISTRING( "com.sun.star.setup.UpdateCheckUI" ), xContext ), 234*cdf0e10cSrcweir uno::UNO_QUERY_THROW); 235*cdf0e10cSrcweir 236*cdf0e10cSrcweir xMenuBarUI->setPropertyValue( PROPERTY_CLICK_HDL, uno::makeAny( xJob ) ); 237*cdf0e10cSrcweir 238*cdf0e10cSrcweir return xMenuBarUI; 239*cdf0e10cSrcweir } 240*cdf0e10cSrcweir 241*cdf0e10cSrcweir //------------------------------------------------------------------------------ 242*cdf0e10cSrcweir 243*cdf0e10cSrcweir 244*cdf0e10cSrcweir 245*cdf0e10cSrcweir typedef sal_Bool (* OnlineCheckFunc) (); 246*cdf0e10cSrcweir 247*cdf0e10cSrcweir class UpdateCheckThread : public WorkerThread 248*cdf0e10cSrcweir { 249*cdf0e10cSrcweir 250*cdf0e10cSrcweir public: 251*cdf0e10cSrcweir UpdateCheckThread( osl::Condition& rCondition, 252*cdf0e10cSrcweir const uno::Reference<uno::XComponentContext>& xContext ); 253*cdf0e10cSrcweir 254*cdf0e10cSrcweir virtual void SAL_CALL join(); 255*cdf0e10cSrcweir virtual void SAL_CALL terminate(); 256*cdf0e10cSrcweir virtual void SAL_CALL cancel(); 257*cdf0e10cSrcweir 258*cdf0e10cSrcweir protected: 259*cdf0e10cSrcweir virtual ~UpdateCheckThread(); 260*cdf0e10cSrcweir 261*cdf0e10cSrcweir virtual void SAL_CALL run(); 262*cdf0e10cSrcweir virtual void SAL_CALL onTerminated(); 263*cdf0e10cSrcweir 264*cdf0e10cSrcweir /* Wrapper around checkForUpdates */ 265*cdf0e10cSrcweir bool runCheck( bool & rbExtensionsChecked ); 266*cdf0e10cSrcweir 267*cdf0e10cSrcweir private: 268*cdf0e10cSrcweir 269*cdf0e10cSrcweir /* Used to avoid dialup login windows (on platforms we know how to double this) */ 270*cdf0e10cSrcweir inline bool hasInternetConnection() const 271*cdf0e10cSrcweir { 272*cdf0e10cSrcweir if(m_pHasInternetConnection != NULL ) 273*cdf0e10cSrcweir return (sal_True == m_pHasInternetConnection()); 274*cdf0e10cSrcweir return true; 275*cdf0e10cSrcweir } 276*cdf0e10cSrcweir 277*cdf0e10cSrcweir /* Creates a new instance of UpdateInformationProvider and returns this instance */ 278*cdf0e10cSrcweir inline uno::Reference<deployment::XUpdateInformationProvider> createProvider() 279*cdf0e10cSrcweir { 280*cdf0e10cSrcweir osl::MutexGuard aGuard(m_aMutex); 281*cdf0e10cSrcweir m_xProvider = deployment::UpdateInformationProvider::create(m_xContext); 282*cdf0e10cSrcweir return m_xProvider; 283*cdf0e10cSrcweir }; 284*cdf0e10cSrcweir 285*cdf0e10cSrcweir /* Returns the remembered instance of UpdateInformationProvider if any */ 286*cdf0e10cSrcweir inline uno::Reference<deployment::XUpdateInformationProvider> getProvider() 287*cdf0e10cSrcweir { osl::MutexGuard aGuard(m_aMutex); return m_xProvider; }; 288*cdf0e10cSrcweir 289*cdf0e10cSrcweir /* Releases the remembered instance of UpdateInformationProvider if any */ 290*cdf0e10cSrcweir inline void clearProvider() 291*cdf0e10cSrcweir { osl::MutexGuard aGuard(m_aMutex); m_xProvider.clear(); }; 292*cdf0e10cSrcweir 293*cdf0e10cSrcweir osl::Mutex m_aMutex; 294*cdf0e10cSrcweir osl::Module m_aModule; 295*cdf0e10cSrcweir 296*cdf0e10cSrcweir protected: 297*cdf0e10cSrcweir osl::Condition& m_aCondition; 298*cdf0e10cSrcweir 299*cdf0e10cSrcweir private: 300*cdf0e10cSrcweir 301*cdf0e10cSrcweir // const 302*cdf0e10cSrcweir OnlineCheckFunc m_pHasInternetConnection; 303*cdf0e10cSrcweir 304*cdf0e10cSrcweir const uno::Reference<uno::XComponentContext> m_xContext; 305*cdf0e10cSrcweir uno::Reference<deployment::XUpdateInformationProvider> m_xProvider; 306*cdf0e10cSrcweir }; 307*cdf0e10cSrcweir 308*cdf0e10cSrcweir 309*cdf0e10cSrcweir class ManualUpdateCheckThread : public UpdateCheckThread 310*cdf0e10cSrcweir { 311*cdf0e10cSrcweir public: 312*cdf0e10cSrcweir ManualUpdateCheckThread( osl::Condition& rCondition, const uno::Reference<uno::XComponentContext>& xContext ) : 313*cdf0e10cSrcweir UpdateCheckThread(rCondition, xContext) {}; 314*cdf0e10cSrcweir 315*cdf0e10cSrcweir virtual void SAL_CALL run(); 316*cdf0e10cSrcweir }; 317*cdf0e10cSrcweir 318*cdf0e10cSrcweir 319*cdf0e10cSrcweir class MenuBarButtonJob : public ::cppu::WeakImplHelper1< task::XJob > 320*cdf0e10cSrcweir { 321*cdf0e10cSrcweir public: 322*cdf0e10cSrcweir MenuBarButtonJob(const rtl::Reference< UpdateCheck >& rUpdateCheck); 323*cdf0e10cSrcweir 324*cdf0e10cSrcweir // XJob 325*cdf0e10cSrcweir virtual uno::Any SAL_CALL execute(const uno::Sequence<beans::NamedValue>&) 326*cdf0e10cSrcweir throw (lang::IllegalArgumentException, uno::Exception); 327*cdf0e10cSrcweir 328*cdf0e10cSrcweir private: 329*cdf0e10cSrcweir rtl::Reference< UpdateCheck > m_aUpdateCheck; 330*cdf0e10cSrcweir }; 331*cdf0e10cSrcweir 332*cdf0e10cSrcweir class DownloadThread : public WorkerThread 333*cdf0e10cSrcweir { 334*cdf0e10cSrcweir public: 335*cdf0e10cSrcweir DownloadThread( 336*cdf0e10cSrcweir osl::Condition& rCondition, 337*cdf0e10cSrcweir const uno::Reference<uno::XComponentContext>& xContext, 338*cdf0e10cSrcweir const rtl::Reference< DownloadInteractionHandler >& rHandler, 339*cdf0e10cSrcweir const rtl::OUString& rURL ); 340*cdf0e10cSrcweir 341*cdf0e10cSrcweir virtual void SAL_CALL run(); 342*cdf0e10cSrcweir virtual void SAL_CALL cancel(); 343*cdf0e10cSrcweir virtual void SAL_CALL suspend(); 344*cdf0e10cSrcweir virtual void SAL_CALL onTerminated(); 345*cdf0e10cSrcweir 346*cdf0e10cSrcweir protected: 347*cdf0e10cSrcweir ~DownloadThread(); 348*cdf0e10cSrcweir 349*cdf0e10cSrcweir private: 350*cdf0e10cSrcweir osl::Condition& m_aCondition; 351*cdf0e10cSrcweir const uno::Reference<uno::XComponentContext> m_xContext; 352*cdf0e10cSrcweir const rtl::OUString m_aURL; 353*cdf0e10cSrcweir Download m_aDownload; 354*cdf0e10cSrcweir }; 355*cdf0e10cSrcweir 356*cdf0e10cSrcweir //------------------------------------------------------------------------------ 357*cdf0e10cSrcweir class ShutdownThread : public osl::Thread 358*cdf0e10cSrcweir { 359*cdf0e10cSrcweir public: 360*cdf0e10cSrcweir ShutdownThread( const uno::Reference<uno::XComponentContext>& xContext ); 361*cdf0e10cSrcweir 362*cdf0e10cSrcweir virtual void SAL_CALL run(); 363*cdf0e10cSrcweir virtual void SAL_CALL onTerminated(); 364*cdf0e10cSrcweir 365*cdf0e10cSrcweir protected: 366*cdf0e10cSrcweir ~ShutdownThread(); 367*cdf0e10cSrcweir 368*cdf0e10cSrcweir private: 369*cdf0e10cSrcweir osl::Condition m_aCondition; 370*cdf0e10cSrcweir const uno::Reference<uno::XComponentContext> m_xContext; 371*cdf0e10cSrcweir }; 372*cdf0e10cSrcweir 373*cdf0e10cSrcweir //------------------------------------------------------------------------------ 374*cdf0e10cSrcweir 375*cdf0e10cSrcweir UpdateCheckThread::UpdateCheckThread( osl::Condition& rCondition, 376*cdf0e10cSrcweir const uno::Reference<uno::XComponentContext>& xContext ) : 377*cdf0e10cSrcweir m_aCondition(rCondition), 378*cdf0e10cSrcweir m_pHasInternetConnection(NULL), 379*cdf0e10cSrcweir m_xContext(xContext) 380*cdf0e10cSrcweir { 381*cdf0e10cSrcweir 382*cdf0e10cSrcweir #ifdef WNT 383*cdf0e10cSrcweir rtl::OUString aPath; 384*cdf0e10cSrcweir if( osl_getExecutableFile(&aPath.pData) == osl_Process_E_None ) 385*cdf0e10cSrcweir { 386*cdf0e10cSrcweir sal_uInt32 lastIndex = aPath.lastIndexOf('/'); 387*cdf0e10cSrcweir if ( lastIndex > 0 ) 388*cdf0e10cSrcweir { 389*cdf0e10cSrcweir aPath = aPath.copy( 0, lastIndex+1 ); 390*cdf0e10cSrcweir aPath += UNISTRING( "onlinecheck" ); 391*cdf0e10cSrcweir } 392*cdf0e10cSrcweir 393*cdf0e10cSrcweir if ( m_aModule.load(aPath) ) 394*cdf0e10cSrcweir { 395*cdf0e10cSrcweir m_pHasInternetConnection = 396*cdf0e10cSrcweir reinterpret_cast < OnlineCheckFunc > ( 397*cdf0e10cSrcweir m_aModule.getFunctionSymbol( UNISTRING("hasInternetConnection"))); 398*cdf0e10cSrcweir } 399*cdf0e10cSrcweir } 400*cdf0e10cSrcweir #endif 401*cdf0e10cSrcweir 402*cdf0e10cSrcweir createSuspended(); 403*cdf0e10cSrcweir 404*cdf0e10cSrcweir // actually run the thread 405*cdf0e10cSrcweir resume(); 406*cdf0e10cSrcweir } 407*cdf0e10cSrcweir 408*cdf0e10cSrcweir //------------------------------------------------------------------------------ 409*cdf0e10cSrcweir 410*cdf0e10cSrcweir UpdateCheckThread::~UpdateCheckThread() 411*cdf0e10cSrcweir { 412*cdf0e10cSrcweir } 413*cdf0e10cSrcweir 414*cdf0e10cSrcweir //------------------------------------------------------------------------------ 415*cdf0e10cSrcweir 416*cdf0e10cSrcweir 417*cdf0e10cSrcweir void SAL_CALL 418*cdf0e10cSrcweir UpdateCheckThread::terminate() 419*cdf0e10cSrcweir { 420*cdf0e10cSrcweir // Cancel potentially hanging http request .. 421*cdf0e10cSrcweir cancel(); 422*cdf0e10cSrcweir // .. before terminating 423*cdf0e10cSrcweir osl::Thread::terminate(); 424*cdf0e10cSrcweir } 425*cdf0e10cSrcweir 426*cdf0e10cSrcweir //------------------------------------------------------------------------------ 427*cdf0e10cSrcweir 428*cdf0e10cSrcweir void SAL_CALL 429*cdf0e10cSrcweir UpdateCheckThread::join() 430*cdf0e10cSrcweir { 431*cdf0e10cSrcweir uno::Reference< deployment::XUpdateInformationProvider > xProvider(getProvider()); 432*cdf0e10cSrcweir 433*cdf0e10cSrcweir // do not join during an update check until #i73893# is fixed 434*cdf0e10cSrcweir if( ! xProvider.is() ) 435*cdf0e10cSrcweir { 436*cdf0e10cSrcweir osl::Thread::join(); 437*cdf0e10cSrcweir } 438*cdf0e10cSrcweir } 439*cdf0e10cSrcweir 440*cdf0e10cSrcweir //------------------------------------------------------------------------------ 441*cdf0e10cSrcweir 442*cdf0e10cSrcweir void SAL_CALL 443*cdf0e10cSrcweir UpdateCheckThread::cancel() 444*cdf0e10cSrcweir { 445*cdf0e10cSrcweir uno::Reference< deployment::XUpdateInformationProvider > xProvider(getProvider()); 446*cdf0e10cSrcweir 447*cdf0e10cSrcweir if( xProvider.is() ) 448*cdf0e10cSrcweir xProvider->cancel(); 449*cdf0e10cSrcweir } 450*cdf0e10cSrcweir 451*cdf0e10cSrcweir //------------------------------------------------------------------------------ 452*cdf0e10cSrcweir 453*cdf0e10cSrcweir bool 454*cdf0e10cSrcweir UpdateCheckThread::runCheck( bool & rbExtensionsChecked ) 455*cdf0e10cSrcweir { 456*cdf0e10cSrcweir bool ret = false; 457*cdf0e10cSrcweir UpdateState eUIState = UPDATESTATE_NO_UPDATE_AVAIL; 458*cdf0e10cSrcweir 459*cdf0e10cSrcweir UpdateInfo aInfo; 460*cdf0e10cSrcweir rtl::Reference< UpdateCheck > aController(UpdateCheck::get()); 461*cdf0e10cSrcweir 462*cdf0e10cSrcweir if( checkForUpdates(aInfo, m_xContext, aController->getInteractionHandler(), createProvider()) ) 463*cdf0e10cSrcweir { 464*cdf0e10cSrcweir aController->setUpdateInfo(aInfo); 465*cdf0e10cSrcweir eUIState = aController->getUIState(aInfo); 466*cdf0e10cSrcweir ret = true; 467*cdf0e10cSrcweir } 468*cdf0e10cSrcweir else 469*cdf0e10cSrcweir aController->setCheckFailedState(); 470*cdf0e10cSrcweir 471*cdf0e10cSrcweir // We will only look for extension updates, when there is no 'check for office updates' dialog open 472*cdf0e10cSrcweir // and when there was no office update found 473*cdf0e10cSrcweir if ( ( eUIState != UPDATESTATE_UPDATE_AVAIL ) && 474*cdf0e10cSrcweir ( eUIState != UPDATESTATE_UPDATE_NO_DOWNLOAD ) && 475*cdf0e10cSrcweir !aController->isDialogShowing() && 476*cdf0e10cSrcweir !rbExtensionsChecked ) 477*cdf0e10cSrcweir { 478*cdf0e10cSrcweir bool bHasExtensionUpdates = checkForExtensionUpdates( m_xContext ); 479*cdf0e10cSrcweir aController->setHasExtensionUpdates( bHasExtensionUpdates ); 480*cdf0e10cSrcweir if ( bHasExtensionUpdates ) 481*cdf0e10cSrcweir aController->setUIState( UPDATESTATE_EXT_UPD_AVAIL ); 482*cdf0e10cSrcweir rbExtensionsChecked = true; 483*cdf0e10cSrcweir } 484*cdf0e10cSrcweir 485*cdf0e10cSrcweir // joining with this thread is safe again 486*cdf0e10cSrcweir clearProvider(); 487*cdf0e10cSrcweir return ret; 488*cdf0e10cSrcweir } 489*cdf0e10cSrcweir 490*cdf0e10cSrcweir //------------------------------------------------------------------------------ 491*cdf0e10cSrcweir 492*cdf0e10cSrcweir void SAL_CALL 493*cdf0e10cSrcweir UpdateCheckThread::onTerminated() 494*cdf0e10cSrcweir { 495*cdf0e10cSrcweir delete this; 496*cdf0e10cSrcweir } 497*cdf0e10cSrcweir 498*cdf0e10cSrcweir //------------------------------------------------------------------------------ 499*cdf0e10cSrcweir 500*cdf0e10cSrcweir void SAL_CALL 501*cdf0e10cSrcweir UpdateCheckThread::run() 502*cdf0e10cSrcweir { 503*cdf0e10cSrcweir bool bExtensionsChecked = false; 504*cdf0e10cSrcweir TimeValue systime; 505*cdf0e10cSrcweir TimeValue nExtCheckTime; 506*cdf0e10cSrcweir osl_getSystemTime( &nExtCheckTime ); 507*cdf0e10cSrcweir 508*cdf0e10cSrcweir osl::Condition::Result aResult = osl::Condition::result_timeout; 509*cdf0e10cSrcweir TimeValue tv = { 10, 0 }; 510*cdf0e10cSrcweir 511*cdf0e10cSrcweir // Initial wait to avoid doing further time consuming tasks during start-up 512*cdf0e10cSrcweir aResult = m_aCondition.wait(&tv); 513*cdf0e10cSrcweir 514*cdf0e10cSrcweir try { 515*cdf0e10cSrcweir 516*cdf0e10cSrcweir while( sal_True == schedule() ) 517*cdf0e10cSrcweir { 518*cdf0e10cSrcweir /* Use cases: 519*cdf0e10cSrcweir * a) manual check requested from auto check thread - "last check" should not be checked (one time) 520*cdf0e10cSrcweir * a1) manual check was requested in the middle of a running auto check, 521*cdf0e10cSrcweir * condition is set 522*cdf0e10cSrcweir * a2) manual check was requested while waiting for a retry, 523*cdf0e10cSrcweir * condition is set 524*cdf0e10cSrcweir * a3) manual check was requested while waiting for time to next 525*cdf0e10cSrcweir * scheduled check elapsing, condition is set 526*cdf0e10cSrcweir * a4) manual check was requested during initial wait, condition is set 527*cdf0e10cSrcweir * b) check interval got changed, condition may be set - same sub-cases as a), 528*cdf0e10cSrcweir * but "last check" should be honored 529*cdf0e10cSrcweir * c) normal auto check mode, condition not set - "last check" should be honored 530*cdf0e10cSrcweir */ 531*cdf0e10cSrcweir 532*cdf0e10cSrcweir // Accessing const members without synchronization 533*cdf0e10cSrcweir rtl::Reference< UpdateCheck > aController(UpdateCheck::get()); 534*cdf0e10cSrcweir rtl::Reference< UpdateCheckConfig > rModel = UpdateCheckConfig::get(m_xContext, *aController); 535*cdf0e10cSrcweir 536*cdf0e10cSrcweir // FIXME: remember last & offset ? 537*cdf0e10cSrcweir sal_Int64 last = rModel->getLastChecked(); 538*cdf0e10cSrcweir sal_Int64 offset = rModel->getCheckInterval(); 539*cdf0e10cSrcweir 540*cdf0e10cSrcweir rModel.clear(); 541*cdf0e10cSrcweir 542*cdf0e10cSrcweir // last == 0 means check immediately 543*cdf0e10cSrcweir bool checkNow = ! (last > 0); 544*cdf0e10cSrcweir 545*cdf0e10cSrcweir // Reset the condition to avoid busy loops 546*cdf0e10cSrcweir if( osl::Condition::result_ok == aResult ) 547*cdf0e10cSrcweir { 548*cdf0e10cSrcweir m_aCondition.reset(); 549*cdf0e10cSrcweir aResult = osl::Condition::result_timeout; 550*cdf0e10cSrcweir checkNow = aController->isDialogShowing(); 551*cdf0e10cSrcweir } 552*cdf0e10cSrcweir 553*cdf0e10cSrcweir if( ! checkNow ) 554*cdf0e10cSrcweir { 555*cdf0e10cSrcweir osl_getSystemTime(&systime); 556*cdf0e10cSrcweir 557*cdf0e10cSrcweir // Go back to sleep until time has elapsed 558*cdf0e10cSrcweir sal_Int64 next = last + offset; 559*cdf0e10cSrcweir if( last + offset > systime.Seconds ) 560*cdf0e10cSrcweir { 561*cdf0e10cSrcweir // This can not be > 32 Bit for now .. 562*cdf0e10cSrcweir tv.Seconds = static_cast< sal_Int32 > (next - systime.Seconds); 563*cdf0e10cSrcweir aResult = m_aCondition.wait(&tv); 564*cdf0e10cSrcweir continue; 565*cdf0e10cSrcweir } 566*cdf0e10cSrcweir } 567*cdf0e10cSrcweir 568*cdf0e10cSrcweir static sal_uInt8 n = 0; 569*cdf0e10cSrcweir 570*cdf0e10cSrcweir if( ! hasInternetConnection() || ! runCheck( bExtensionsChecked ) ) 571*cdf0e10cSrcweir { 572*cdf0e10cSrcweir // the extension update check should be independent from the office update check 573*cdf0e10cSrcweir // 574*cdf0e10cSrcweir osl_getSystemTime( &systime ); 575*cdf0e10cSrcweir if ( nExtCheckTime.Seconds + offset < systime.Seconds ) 576*cdf0e10cSrcweir bExtensionsChecked = false; 577*cdf0e10cSrcweir 578*cdf0e10cSrcweir // Increase next by 15, 60, .. minutes 579*cdf0e10cSrcweir static const sal_Int32 nRetryInterval[] = { 900, 3600, 14400, 86400 }; 580*cdf0e10cSrcweir 581*cdf0e10cSrcweir if( n < sizeof(nRetryInterval) / sizeof(sal_Int32) ) 582*cdf0e10cSrcweir ++n; 583*cdf0e10cSrcweir 584*cdf0e10cSrcweir tv.Seconds = nRetryInterval[n-1]; 585*cdf0e10cSrcweir aResult = m_aCondition.wait(&tv); 586*cdf0e10cSrcweir } 587*cdf0e10cSrcweir else // reset retry counter 588*cdf0e10cSrcweir { 589*cdf0e10cSrcweir n = 0; 590*cdf0e10cSrcweir bExtensionsChecked = false; 591*cdf0e10cSrcweir } 592*cdf0e10cSrcweir } 593*cdf0e10cSrcweir } 594*cdf0e10cSrcweir 595*cdf0e10cSrcweir catch(const uno::Exception& e) { 596*cdf0e10cSrcweir // Silently catch all errors 597*cdf0e10cSrcweir OSL_TRACE( "Caught exception: %s\n thread terminated.\n", 598*cdf0e10cSrcweir rtl::OUStringToOString(e.Message, RTL_TEXTENCODING_UTF8).getStr() ); 599*cdf0e10cSrcweir } 600*cdf0e10cSrcweir } 601*cdf0e10cSrcweir 602*cdf0e10cSrcweir //------------------------------------------------------------------------------ 603*cdf0e10cSrcweir 604*cdf0e10cSrcweir void SAL_CALL 605*cdf0e10cSrcweir ManualUpdateCheckThread::run() 606*cdf0e10cSrcweir { 607*cdf0e10cSrcweir bool bExtensionsChecked = false; 608*cdf0e10cSrcweir 609*cdf0e10cSrcweir try { 610*cdf0e10cSrcweir runCheck( bExtensionsChecked ); 611*cdf0e10cSrcweir m_aCondition.reset(); 612*cdf0e10cSrcweir } 613*cdf0e10cSrcweir catch(const uno::Exception& e) { 614*cdf0e10cSrcweir // Silently catch all errors 615*cdf0e10cSrcweir OSL_TRACE( "Caught exception: %s\n thread terminated.\n", 616*cdf0e10cSrcweir rtl::OUStringToOString(e.Message, RTL_TEXTENCODING_UTF8).getStr() ); 617*cdf0e10cSrcweir } 618*cdf0e10cSrcweir } 619*cdf0e10cSrcweir 620*cdf0e10cSrcweir //------------------------------------------------------------------------------ 621*cdf0e10cSrcweir 622*cdf0e10cSrcweir MenuBarButtonJob::MenuBarButtonJob(const rtl::Reference< UpdateCheck >& rUpdateCheck) : 623*cdf0e10cSrcweir m_aUpdateCheck(rUpdateCheck) 624*cdf0e10cSrcweir { 625*cdf0e10cSrcweir }; 626*cdf0e10cSrcweir 627*cdf0e10cSrcweir //------------------------------------------------------------------------------ 628*cdf0e10cSrcweir 629*cdf0e10cSrcweir uno::Any SAL_CALL 630*cdf0e10cSrcweir MenuBarButtonJob::execute(const uno::Sequence<beans::NamedValue>& ) 631*cdf0e10cSrcweir throw (lang::IllegalArgumentException, uno::Exception) 632*cdf0e10cSrcweir { 633*cdf0e10cSrcweir if ( m_aUpdateCheck->shouldShowExtUpdDlg() ) 634*cdf0e10cSrcweir m_aUpdateCheck->showExtensionDialog(); 635*cdf0e10cSrcweir else 636*cdf0e10cSrcweir m_aUpdateCheck->showDialog(); 637*cdf0e10cSrcweir 638*cdf0e10cSrcweir return uno::Any(); 639*cdf0e10cSrcweir } 640*cdf0e10cSrcweir 641*cdf0e10cSrcweir //------------------------------------------------------------------------------ 642*cdf0e10cSrcweir 643*cdf0e10cSrcweir DownloadThread::DownloadThread(osl::Condition& rCondition, 644*cdf0e10cSrcweir const uno::Reference<uno::XComponentContext>& xContext, 645*cdf0e10cSrcweir const rtl::Reference< DownloadInteractionHandler >& rHandler, 646*cdf0e10cSrcweir const rtl::OUString& rURL) : 647*cdf0e10cSrcweir m_aCondition(rCondition), 648*cdf0e10cSrcweir m_xContext(xContext), 649*cdf0e10cSrcweir m_aURL(rURL), 650*cdf0e10cSrcweir m_aDownload(xContext, rHandler) 651*cdf0e10cSrcweir { 652*cdf0e10cSrcweir createSuspended(); 653*cdf0e10cSrcweir } 654*cdf0e10cSrcweir 655*cdf0e10cSrcweir //------------------------------------------------------------------------------ 656*cdf0e10cSrcweir 657*cdf0e10cSrcweir DownloadThread::~DownloadThread() 658*cdf0e10cSrcweir { 659*cdf0e10cSrcweir } 660*cdf0e10cSrcweir 661*cdf0e10cSrcweir //------------------------------------------------------------------------------ 662*cdf0e10cSrcweir 663*cdf0e10cSrcweir void SAL_CALL 664*cdf0e10cSrcweir DownloadThread::run() 665*cdf0e10cSrcweir { 666*cdf0e10cSrcweir #ifdef WNT 667*cdf0e10cSrcweir CoUninitialize(); 668*cdf0e10cSrcweir CoInitialize( NULL ); 669*cdf0e10cSrcweir #endif 670*cdf0e10cSrcweir 671*cdf0e10cSrcweir while( schedule() ) 672*cdf0e10cSrcweir { 673*cdf0e10cSrcweir rtl::Reference< UpdateCheckConfig > rModel = UpdateCheckConfig::get(m_xContext); 674*cdf0e10cSrcweir 675*cdf0e10cSrcweir rtl::OUString aLocalFile = rModel->getLocalFileName(); 676*cdf0e10cSrcweir rtl::OUString aDownloadDest = rModel->getDownloadDestination(); 677*cdf0e10cSrcweir 678*cdf0e10cSrcweir // release config class for now 679*cdf0e10cSrcweir rModel.clear(); 680*cdf0e10cSrcweir 681*cdf0e10cSrcweir static sal_uInt8 n = 0; 682*cdf0e10cSrcweir if( ! m_aDownload.start(m_aURL, aLocalFile, aDownloadDest ) ) 683*cdf0e10cSrcweir { 684*cdf0e10cSrcweir // retry every 15s unless the dialog is not visible 685*cdf0e10cSrcweir TimeValue tv; 686*cdf0e10cSrcweir tv.Seconds = 15; 687*cdf0e10cSrcweir 688*cdf0e10cSrcweir if( ! UpdateCheck::get()->isDialogShowing() ) 689*cdf0e10cSrcweir { 690*cdf0e10cSrcweir // Increase next by 1, 5, 15, 60, .. minutes 691*cdf0e10cSrcweir static const sal_Int16 nRetryInterval[] = { 60, 300, 900, 3600 }; 692*cdf0e10cSrcweir 693*cdf0e10cSrcweir if( n < sizeof(nRetryInterval) / sizeof(sal_Int16) ) 694*cdf0e10cSrcweir ++n; 695*cdf0e10cSrcweir 696*cdf0e10cSrcweir tv.Seconds = nRetryInterval[n-1]; 697*cdf0e10cSrcweir } 698*cdf0e10cSrcweir m_aCondition.wait(&tv); 699*cdf0e10cSrcweir } 700*cdf0e10cSrcweir else 701*cdf0e10cSrcweir { 702*cdf0e10cSrcweir // reset wait period after successful download 703*cdf0e10cSrcweir n=0; 704*cdf0e10cSrcweir } 705*cdf0e10cSrcweir } 706*cdf0e10cSrcweir } 707*cdf0e10cSrcweir 708*cdf0e10cSrcweir //------------------------------------------------------------------------------ 709*cdf0e10cSrcweir 710*cdf0e10cSrcweir void SAL_CALL DownloadThread::cancel() 711*cdf0e10cSrcweir { 712*cdf0e10cSrcweir m_aDownload.stop(); 713*cdf0e10cSrcweir resume(); 714*cdf0e10cSrcweir 715*cdf0e10cSrcweir rtl::Reference< UpdateCheck > aController(UpdateCheck::get()); 716*cdf0e10cSrcweir aController->cancelDownload(); 717*cdf0e10cSrcweir } 718*cdf0e10cSrcweir 719*cdf0e10cSrcweir //------------------------------------------------------------------------------ 720*cdf0e10cSrcweir 721*cdf0e10cSrcweir void SAL_CALL DownloadThread::suspend() 722*cdf0e10cSrcweir { 723*cdf0e10cSrcweir osl::Thread::suspend(); 724*cdf0e10cSrcweir m_aDownload.stop(); 725*cdf0e10cSrcweir } 726*cdf0e10cSrcweir 727*cdf0e10cSrcweir //------------------------------------------------------------------------------ 728*cdf0e10cSrcweir 729*cdf0e10cSrcweir void SAL_CALL DownloadThread::onTerminated() 730*cdf0e10cSrcweir { 731*cdf0e10cSrcweir delete this; 732*cdf0e10cSrcweir } 733*cdf0e10cSrcweir 734*cdf0e10cSrcweir //------------------------------------------------------------------------------ 735*cdf0e10cSrcweir ShutdownThread::ShutdownThread( const uno::Reference<uno::XComponentContext>& xContext) : 736*cdf0e10cSrcweir m_xContext( xContext ) 737*cdf0e10cSrcweir { 738*cdf0e10cSrcweir create(); 739*cdf0e10cSrcweir } 740*cdf0e10cSrcweir 741*cdf0e10cSrcweir //------------------------------------------------------------------------------ 742*cdf0e10cSrcweir ShutdownThread::~ShutdownThread() 743*cdf0e10cSrcweir { 744*cdf0e10cSrcweir } 745*cdf0e10cSrcweir 746*cdf0e10cSrcweir //------------------------------------------------------------------------------ 747*cdf0e10cSrcweir void SAL_CALL 748*cdf0e10cSrcweir ShutdownThread::run() 749*cdf0e10cSrcweir { 750*cdf0e10cSrcweir TimeValue tv = { 0, 250 }; 751*cdf0e10cSrcweir 752*cdf0e10cSrcweir m_aCondition.wait(&tv); 753*cdf0e10cSrcweir 754*cdf0e10cSrcweir // Tell QuickStarter not to veto .. 755*cdf0e10cSrcweir uno::Reference< beans::XFastPropertySet > xQuickStarter( 756*cdf0e10cSrcweir UpdateCheck::createService(UNISTRING("com.sun.star.office.Quickstart"), m_xContext), 757*cdf0e10cSrcweir uno::UNO_QUERY 758*cdf0e10cSrcweir ); 759*cdf0e10cSrcweir 760*cdf0e10cSrcweir if (xQuickStarter.is()) 761*cdf0e10cSrcweir xQuickStarter->setFastPropertyValue(0, uno::makeAny(false)); 762*cdf0e10cSrcweir 763*cdf0e10cSrcweir // Shutdown the office 764*cdf0e10cSrcweir uno::Reference< frame::XDesktop > xDesktop( 765*cdf0e10cSrcweir UpdateCheck::createService(UNISTRING("com.sun.star.frame.Desktop"), m_xContext), 766*cdf0e10cSrcweir uno::UNO_QUERY); 767*cdf0e10cSrcweir 768*cdf0e10cSrcweir if( xDesktop.is() ) 769*cdf0e10cSrcweir xDesktop->terminate(); 770*cdf0e10cSrcweir } 771*cdf0e10cSrcweir 772*cdf0e10cSrcweir //------------------------------------------------------------------------------ 773*cdf0e10cSrcweir void SAL_CALL ShutdownThread::onTerminated() 774*cdf0e10cSrcweir { 775*cdf0e10cSrcweir delete this; 776*cdf0e10cSrcweir } 777*cdf0e10cSrcweir 778*cdf0e10cSrcweir //------------------------------------------------------------------------------ 779*cdf0e10cSrcweir 780*cdf0e10cSrcweir } // anonymous namespace 781*cdf0e10cSrcweir 782*cdf0e10cSrcweir 783*cdf0e10cSrcweir //------------------------------------------------------------------------------ 784*cdf0e10cSrcweir 785*cdf0e10cSrcweir 786*cdf0e10cSrcweir void 787*cdf0e10cSrcweir UpdateCheck::initialize(const uno::Sequence< beans::NamedValue >& rValues, 788*cdf0e10cSrcweir const uno::Reference<uno::XComponentContext>& xContext) 789*cdf0e10cSrcweir { 790*cdf0e10cSrcweir osl::MutexGuard aGuard(m_aMutex); 791*cdf0e10cSrcweir 792*cdf0e10cSrcweir if( NOT_INITIALIZED == m_eState ) 793*cdf0e10cSrcweir { 794*cdf0e10cSrcweir NamedValueByNameAccess aNameAccess(rValues); 795*cdf0e10cSrcweir UpdateCheckROModel aModel( aNameAccess ); 796*cdf0e10cSrcweir m_xContext = xContext; 797*cdf0e10cSrcweir 798*cdf0e10cSrcweir rtl::OUString aUpdateEntryVersion = aModel.getUpdateEntryVersion(); 799*cdf0e10cSrcweir 800*cdf0e10cSrcweir aModel.getUpdateEntry(m_aUpdateInfo); 801*cdf0e10cSrcweir 802*cdf0e10cSrcweir bool obsoleteUpdateInfo = isObsoleteUpdateInfo(aUpdateEntryVersion); 803*cdf0e10cSrcweir bool bContinueDownload = false; 804*cdf0e10cSrcweir bool bDownloadAvailable = false; 805*cdf0e10cSrcweir 806*cdf0e10cSrcweir m_bHasExtensionUpdate = checkForPendingUpdates( xContext ); 807*cdf0e10cSrcweir m_bShowExtUpdDlg = false; 808*cdf0e10cSrcweir 809*cdf0e10cSrcweir rtl::OUString aLocalFileName = aModel.getLocalFileName(); 810*cdf0e10cSrcweir 811*cdf0e10cSrcweir if( aLocalFileName.getLength() > 0 ) 812*cdf0e10cSrcweir { 813*cdf0e10cSrcweir bContinueDownload = true; 814*cdf0e10cSrcweir 815*cdf0e10cSrcweir // Try to get the number of bytes already on disk 816*cdf0e10cSrcweir osl::DirectoryItem aDirectoryItem; 817*cdf0e10cSrcweir if( osl::DirectoryItem::E_None == osl::DirectoryItem::get(aLocalFileName, aDirectoryItem) ) 818*cdf0e10cSrcweir { 819*cdf0e10cSrcweir osl::FileStatus aFileStatus(FileStatusMask_FileSize); 820*cdf0e10cSrcweir if( osl::DirectoryItem::E_None == aDirectoryItem.getFileStatus(aFileStatus) ) 821*cdf0e10cSrcweir { 822*cdf0e10cSrcweir sal_Int64 nDownloadSize = aModel.getDownloadSize(); 823*cdf0e10cSrcweir sal_Int64 nFileSize = aFileStatus.getFileSize(); 824*cdf0e10cSrcweir 825*cdf0e10cSrcweir if( nDownloadSize > 0 ) 826*cdf0e10cSrcweir { 827*cdf0e10cSrcweir if ( nDownloadSize <= nFileSize ) // we have already downloaded everthing 828*cdf0e10cSrcweir { 829*cdf0e10cSrcweir bContinueDownload = false; 830*cdf0e10cSrcweir bDownloadAvailable = true; 831*cdf0e10cSrcweir m_aImageName = getImageFromFileName( aLocalFileName ); 832*cdf0e10cSrcweir } 833*cdf0e10cSrcweir else // Calculate initial percent value. 834*cdf0e10cSrcweir { 835*cdf0e10cSrcweir sal_Int32 nPercent = (sal_Int32) (100 * nFileSize / nDownloadSize); 836*cdf0e10cSrcweir getUpdateHandler()->setProgress( nPercent ); 837*cdf0e10cSrcweir } 838*cdf0e10cSrcweir } 839*cdf0e10cSrcweir } 840*cdf0e10cSrcweir } 841*cdf0e10cSrcweir 842*cdf0e10cSrcweir if ( bContinueDownload ) 843*cdf0e10cSrcweir { 844*cdf0e10cSrcweir bool downloadPaused = aModel.isDownloadPaused(); 845*cdf0e10cSrcweir 846*cdf0e10cSrcweir enableDownload(true, downloadPaused); 847*cdf0e10cSrcweir setUIState(downloadPaused ? UPDATESTATE_DOWNLOAD_PAUSED : UPDATESTATE_DOWNLOADING); 848*cdf0e10cSrcweir } 849*cdf0e10cSrcweir 850*cdf0e10cSrcweir } 851*cdf0e10cSrcweir if ( !bContinueDownload ) 852*cdf0e10cSrcweir { 853*cdf0e10cSrcweir // We do this intentionally only if no download is in progress .. 854*cdf0e10cSrcweir if( obsoleteUpdateInfo ) 855*cdf0e10cSrcweir { 856*cdf0e10cSrcweir // Bring-up release note for position 5 .. 857*cdf0e10cSrcweir const rtl::OUString aURL(getReleaseNote(m_aUpdateInfo, 5)); 858*cdf0e10cSrcweir if( aURL.getLength() > 0 ) 859*cdf0e10cSrcweir showReleaseNote(aURL); 860*cdf0e10cSrcweir 861*cdf0e10cSrcweir // Data is outdated, probably due to installed update 862*cdf0e10cSrcweir rtl::Reference< UpdateCheckConfig > aConfig = UpdateCheckConfig::get( xContext, *this ); 863*cdf0e10cSrcweir aConfig->clearUpdateFound(); 864*cdf0e10cSrcweir aConfig->clearLocalFileName(); 865*cdf0e10cSrcweir 866*cdf0e10cSrcweir 867*cdf0e10cSrcweir m_aUpdateInfo = UpdateInfo(); 868*cdf0e10cSrcweir // Remove outdated release notes 869*cdf0e10cSrcweir storeReleaseNote( 1, rtl::OUString() ); 870*cdf0e10cSrcweir storeReleaseNote( 2, rtl::OUString() ); 871*cdf0e10cSrcweir } 872*cdf0e10cSrcweir else 873*cdf0e10cSrcweir { 874*cdf0e10cSrcweir enableAutoCheck(aModel.isAutoCheckEnabled()); 875*cdf0e10cSrcweir if ( bDownloadAvailable ) 876*cdf0e10cSrcweir setUIState( UPDATESTATE_DOWNLOAD_AVAIL ); 877*cdf0e10cSrcweir else 878*cdf0e10cSrcweir setUIState(getUIState(m_aUpdateInfo)); 879*cdf0e10cSrcweir } 880*cdf0e10cSrcweir } 881*cdf0e10cSrcweir } 882*cdf0e10cSrcweir } 883*cdf0e10cSrcweir 884*cdf0e10cSrcweir //------------------------------------------------------------------------------ 885*cdf0e10cSrcweir 886*cdf0e10cSrcweir void 887*cdf0e10cSrcweir UpdateCheck::cancel() 888*cdf0e10cSrcweir { 889*cdf0e10cSrcweir osl::ClearableMutexGuard aGuard(m_aMutex); 890*cdf0e10cSrcweir 891*cdf0e10cSrcweir WorkerThread *pThread = m_pThread; 892*cdf0e10cSrcweir UpdateState eUIState = getUIState(m_aUpdateInfo); 893*cdf0e10cSrcweir 894*cdf0e10cSrcweir aGuard.clear(); 895*cdf0e10cSrcweir 896*cdf0e10cSrcweir if( NULL != pThread ) 897*cdf0e10cSrcweir pThread->cancel(); 898*cdf0e10cSrcweir 899*cdf0e10cSrcweir setUIState(eUIState); 900*cdf0e10cSrcweir } 901*cdf0e10cSrcweir 902*cdf0e10cSrcweir //------------------------------------------------------------------------------ 903*cdf0e10cSrcweir 904*cdf0e10cSrcweir void 905*cdf0e10cSrcweir UpdateCheck::download() 906*cdf0e10cSrcweir { 907*cdf0e10cSrcweir osl::ClearableMutexGuard aGuard(m_aMutex); 908*cdf0e10cSrcweir UpdateInfo aInfo(m_aUpdateInfo); 909*cdf0e10cSrcweir State eState = m_eState; 910*cdf0e10cSrcweir aGuard.clear(); 911*cdf0e10cSrcweir 912*cdf0e10cSrcweir if( aInfo.Sources[0].IsDirect ) 913*cdf0e10cSrcweir { 914*cdf0e10cSrcweir // Ignore second click of a double click 915*cdf0e10cSrcweir if( DOWNLOADING != eState ) 916*cdf0e10cSrcweir { 917*cdf0e10cSrcweir shutdownThread(true); 918*cdf0e10cSrcweir 919*cdf0e10cSrcweir osl::ClearableMutexGuard aGuard2(m_aMutex); 920*cdf0e10cSrcweir enableDownload(true); 921*cdf0e10cSrcweir aGuard2.clear(); 922*cdf0e10cSrcweir setUIState(UPDATESTATE_DOWNLOADING); 923*cdf0e10cSrcweir } 924*cdf0e10cSrcweir } 925*cdf0e10cSrcweir else 926*cdf0e10cSrcweir { 927*cdf0e10cSrcweir showReleaseNote(aInfo.Sources[0].URL); // Display in browser 928*cdf0e10cSrcweir } 929*cdf0e10cSrcweir } 930*cdf0e10cSrcweir 931*cdf0e10cSrcweir //------------------------------------------------------------------------------ 932*cdf0e10cSrcweir 933*cdf0e10cSrcweir void 934*cdf0e10cSrcweir UpdateCheck::install() 935*cdf0e10cSrcweir { 936*cdf0e10cSrcweir osl::MutexGuard aGuard(m_aMutex); 937*cdf0e10cSrcweir 938*cdf0e10cSrcweir const uno::Reference< c3s::XSystemShellExecute > xShellExecute( 939*cdf0e10cSrcweir createService( UNISTRING( "com.sun.star.system.SystemShellExecute" ), m_xContext ), 940*cdf0e10cSrcweir uno::UNO_QUERY ); 941*cdf0e10cSrcweir 942*cdf0e10cSrcweir try { 943*cdf0e10cSrcweir // Construct install command ?? 944*cdf0e10cSrcweir 945*cdf0e10cSrcweir // Store release note for position 3 and 4 946*cdf0e10cSrcweir rtl::OUString aURL(getReleaseNote(m_aUpdateInfo, 3)); 947*cdf0e10cSrcweir storeReleaseNote(1, aURL); 948*cdf0e10cSrcweir 949*cdf0e10cSrcweir aURL = getReleaseNote(m_aUpdateInfo, 4); 950*cdf0e10cSrcweir storeReleaseNote(2, aURL); 951*cdf0e10cSrcweir 952*cdf0e10cSrcweir if( xShellExecute.is() ) 953*cdf0e10cSrcweir { 954*cdf0e10cSrcweir rtl::OUString aInstallImage(m_aImageName); 955*cdf0e10cSrcweir osl::FileBase::getSystemPathFromFileURL(aInstallImage, aInstallImage); 956*cdf0e10cSrcweir 957*cdf0e10cSrcweir rtl::OUString aParameter; 958*cdf0e10cSrcweir sal_Int32 nFlags = c3s::SystemShellExecuteFlags::DEFAULTS; 959*cdf0e10cSrcweir #if ( defined LINUX || defined SOLARIS ) 960*cdf0e10cSrcweir nFlags = 42; 961*cdf0e10cSrcweir aParameter = getBaseInstallation(); 962*cdf0e10cSrcweir if( aParameter.getLength() > 0 ) 963*cdf0e10cSrcweir osl::FileBase::getSystemPathFromFileURL(aParameter, aParameter); 964*cdf0e10cSrcweir 965*cdf0e10cSrcweir aParameter += UNISTRING(" &"); 966*cdf0e10cSrcweir #endif 967*cdf0e10cSrcweir 968*cdf0e10cSrcweir rtl::Reference< UpdateCheckConfig > rModel = UpdateCheckConfig::get( m_xContext ); 969*cdf0e10cSrcweir rModel->clearLocalFileName(); 970*cdf0e10cSrcweir 971*cdf0e10cSrcweir xShellExecute->execute(aInstallImage, aParameter, nFlags); 972*cdf0e10cSrcweir ShutdownThread *pShutdownThread = new ShutdownThread( m_xContext ); 973*cdf0e10cSrcweir (void) pShutdownThread; 974*cdf0e10cSrcweir } 975*cdf0e10cSrcweir } catch(uno::Exception&) { 976*cdf0e10cSrcweir m_aUpdateHandler->setErrorMessage( m_aUpdateHandler->getDefaultInstErrMsg() ); 977*cdf0e10cSrcweir } 978*cdf0e10cSrcweir } 979*cdf0e10cSrcweir 980*cdf0e10cSrcweir //------------------------------------------------------------------------------ 981*cdf0e10cSrcweir 982*cdf0e10cSrcweir void 983*cdf0e10cSrcweir UpdateCheck::pause() 984*cdf0e10cSrcweir { 985*cdf0e10cSrcweir osl::ClearableMutexGuard aGuard(m_aMutex); 986*cdf0e10cSrcweir 987*cdf0e10cSrcweir if( NULL != m_pThread ) 988*cdf0e10cSrcweir m_pThread->suspend(); 989*cdf0e10cSrcweir 990*cdf0e10cSrcweir rtl::Reference< UpdateCheckConfig > rModel = UpdateCheckConfig::get(m_xContext); 991*cdf0e10cSrcweir aGuard.clear(); 992*cdf0e10cSrcweir 993*cdf0e10cSrcweir rModel->storeDownloadPaused(true); 994*cdf0e10cSrcweir setUIState(UPDATESTATE_DOWNLOAD_PAUSED); 995*cdf0e10cSrcweir } 996*cdf0e10cSrcweir 997*cdf0e10cSrcweir //------------------------------------------------------------------------------ 998*cdf0e10cSrcweir 999*cdf0e10cSrcweir void 1000*cdf0e10cSrcweir UpdateCheck::resume() 1001*cdf0e10cSrcweir { 1002*cdf0e10cSrcweir osl::ClearableMutexGuard aGuard(m_aMutex); 1003*cdf0e10cSrcweir 1004*cdf0e10cSrcweir if( NULL != m_pThread ) 1005*cdf0e10cSrcweir m_pThread->resume(); 1006*cdf0e10cSrcweir 1007*cdf0e10cSrcweir rtl::Reference< UpdateCheckConfig > rModel = UpdateCheckConfig::get(m_xContext); 1008*cdf0e10cSrcweir aGuard.clear(); 1009*cdf0e10cSrcweir 1010*cdf0e10cSrcweir rModel->storeDownloadPaused(false); 1011*cdf0e10cSrcweir setUIState(UPDATESTATE_DOWNLOADING); 1012*cdf0e10cSrcweir } 1013*cdf0e10cSrcweir 1014*cdf0e10cSrcweir //------------------------------------------------------------------------------ 1015*cdf0e10cSrcweir 1016*cdf0e10cSrcweir void 1017*cdf0e10cSrcweir UpdateCheck::closeAfterFailure() 1018*cdf0e10cSrcweir { 1019*cdf0e10cSrcweir osl::ClearableMutexGuard aGuard(m_aMutex); 1020*cdf0e10cSrcweir 1021*cdf0e10cSrcweir if ( ( m_eState == DISABLED ) || ( m_eState == CHECK_SCHEDULED ) ) 1022*cdf0e10cSrcweir { 1023*cdf0e10cSrcweir const UpdateState eUIState = getUIState( m_aUpdateInfo ); 1024*cdf0e10cSrcweir aGuard.clear(); 1025*cdf0e10cSrcweir setUIState( eUIState, true ); 1026*cdf0e10cSrcweir } 1027*cdf0e10cSrcweir } 1028*cdf0e10cSrcweir 1029*cdf0e10cSrcweir //------------------------------------------------------------------------------ 1030*cdf0e10cSrcweir 1031*cdf0e10cSrcweir void 1032*cdf0e10cSrcweir UpdateCheck::shutdownThread(bool join) 1033*cdf0e10cSrcweir { 1034*cdf0e10cSrcweir osl::ClearableMutexGuard aGuard(m_aMutex); 1035*cdf0e10cSrcweir 1036*cdf0e10cSrcweir // copy thread object pointer to stack 1037*cdf0e10cSrcweir osl::Thread *pThread = m_pThread; 1038*cdf0e10cSrcweir m_pThread = NULL; 1039*cdf0e10cSrcweir aGuard.clear(); 1040*cdf0e10cSrcweir 1041*cdf0e10cSrcweir if( NULL != pThread ) 1042*cdf0e10cSrcweir { 1043*cdf0e10cSrcweir pThread->terminate(); 1044*cdf0e10cSrcweir if( join ) 1045*cdf0e10cSrcweir { 1046*cdf0e10cSrcweir m_aCondition.set(); 1047*cdf0e10cSrcweir pThread->join(); 1048*cdf0e10cSrcweir m_aCondition.reset(); 1049*cdf0e10cSrcweir } 1050*cdf0e10cSrcweir } 1051*cdf0e10cSrcweir } 1052*cdf0e10cSrcweir 1053*cdf0e10cSrcweir //------------------------------------------------------------------------------ 1054*cdf0e10cSrcweir 1055*cdf0e10cSrcweir void 1056*cdf0e10cSrcweir UpdateCheck::enableAutoCheck(bool enable) 1057*cdf0e10cSrcweir { 1058*cdf0e10cSrcweir if( enable ) 1059*cdf0e10cSrcweir m_pThread = new UpdateCheckThread(m_aCondition, m_xContext); 1060*cdf0e10cSrcweir 1061*cdf0e10cSrcweir m_eState = enable ? CHECK_SCHEDULED : DISABLED; 1062*cdf0e10cSrcweir } 1063*cdf0e10cSrcweir 1064*cdf0e10cSrcweir //------------------------------------------------------------------------------ 1065*cdf0e10cSrcweir 1066*cdf0e10cSrcweir void 1067*cdf0e10cSrcweir UpdateCheck::enableDownload(bool enable, bool paused) 1068*cdf0e10cSrcweir { 1069*cdf0e10cSrcweir OSL_ASSERT(NULL == m_pThread); 1070*cdf0e10cSrcweir 1071*cdf0e10cSrcweir State eState = DISABLED; 1072*cdf0e10cSrcweir if( enable ) 1073*cdf0e10cSrcweir { 1074*cdf0e10cSrcweir m_pThread = new DownloadThread(m_aCondition, m_xContext, this, m_aUpdateInfo.Sources[0].URL ); 1075*cdf0e10cSrcweir if( !paused ) 1076*cdf0e10cSrcweir { 1077*cdf0e10cSrcweir eState = DOWNLOADING; 1078*cdf0e10cSrcweir m_pThread->resume(); 1079*cdf0e10cSrcweir } 1080*cdf0e10cSrcweir else 1081*cdf0e10cSrcweir eState = DOWNLOAD_PAUSED; 1082*cdf0e10cSrcweir 1083*cdf0e10cSrcweir m_eState = eState; 1084*cdf0e10cSrcweir } 1085*cdf0e10cSrcweir else { 1086*cdf0e10cSrcweir enableAutoCheck(UpdateCheckConfig::get(m_xContext)->isAutoCheckEnabled()); 1087*cdf0e10cSrcweir } 1088*cdf0e10cSrcweir 1089*cdf0e10cSrcweir } 1090*cdf0e10cSrcweir 1091*cdf0e10cSrcweir //------------------------------------------------------------------------------ 1092*cdf0e10cSrcweir 1093*cdf0e10cSrcweir bool 1094*cdf0e10cSrcweir UpdateCheck::downloadTargetExists(const rtl::OUString& rFileName) 1095*cdf0e10cSrcweir { 1096*cdf0e10cSrcweir osl::ClearableMutexGuard aGuard(m_aMutex); 1097*cdf0e10cSrcweir 1098*cdf0e10cSrcweir rtl::Reference< UpdateHandler > aUpdateHandler(getUpdateHandler()); 1099*cdf0e10cSrcweir UpdateState eUIState = UPDATESTATE_DOWNLOADING; 1100*cdf0e10cSrcweir 1101*cdf0e10cSrcweir bool cont = false; 1102*cdf0e10cSrcweir 1103*cdf0e10cSrcweir if( aUpdateHandler->isVisible() ) 1104*cdf0e10cSrcweir { 1105*cdf0e10cSrcweir cont = aUpdateHandler->showOverwriteWarning(); 1106*cdf0e10cSrcweir if( cont ) 1107*cdf0e10cSrcweir { 1108*cdf0e10cSrcweir if( osl_File_E_None != osl_removeFile(rFileName.pData) ) 1109*cdf0e10cSrcweir { 1110*cdf0e10cSrcweir // FIXME: error message 1111*cdf0e10cSrcweir cont = false; 1112*cdf0e10cSrcweir } 1113*cdf0e10cSrcweir } 1114*cdf0e10cSrcweir else 1115*cdf0e10cSrcweir eUIState = getUIState(m_aUpdateInfo); 1116*cdf0e10cSrcweir } 1117*cdf0e10cSrcweir else 1118*cdf0e10cSrcweir { 1119*cdf0e10cSrcweir m_aImageName = getImageFromFileName(rFileName); 1120*cdf0e10cSrcweir eUIState = UPDATESTATE_DOWNLOAD_AVAIL; 1121*cdf0e10cSrcweir } 1122*cdf0e10cSrcweir 1123*cdf0e10cSrcweir if( !cont ) 1124*cdf0e10cSrcweir { 1125*cdf0e10cSrcweir shutdownThread(false); 1126*cdf0e10cSrcweir enableDownload(false); 1127*cdf0e10cSrcweir 1128*cdf0e10cSrcweir aGuard.clear(); 1129*cdf0e10cSrcweir setUIState(eUIState); 1130*cdf0e10cSrcweir } 1131*cdf0e10cSrcweir 1132*cdf0e10cSrcweir return cont; 1133*cdf0e10cSrcweir } 1134*cdf0e10cSrcweir 1135*cdf0e10cSrcweir //------------------------------------------------------------------------------ 1136*cdf0e10cSrcweir bool UpdateCheck::checkDownloadDestination( const rtl::OUString& rFileName ) 1137*cdf0e10cSrcweir { 1138*cdf0e10cSrcweir osl::ClearableMutexGuard aGuard(m_aMutex); 1139*cdf0e10cSrcweir 1140*cdf0e10cSrcweir rtl::Reference< UpdateHandler > aUpdateHandler( getUpdateHandler() ); 1141*cdf0e10cSrcweir 1142*cdf0e10cSrcweir bool bReload = false; 1143*cdf0e10cSrcweir 1144*cdf0e10cSrcweir if( aUpdateHandler->isVisible() ) 1145*cdf0e10cSrcweir { 1146*cdf0e10cSrcweir bReload = aUpdateHandler->showOverwriteWarning( rFileName ); 1147*cdf0e10cSrcweir } 1148*cdf0e10cSrcweir 1149*cdf0e10cSrcweir return bReload; 1150*cdf0e10cSrcweir } 1151*cdf0e10cSrcweir 1152*cdf0e10cSrcweir //------------------------------------------------------------------------------ 1153*cdf0e10cSrcweir 1154*cdf0e10cSrcweir void 1155*cdf0e10cSrcweir UpdateCheck::downloadStalled(const rtl::OUString& rErrorMessage) 1156*cdf0e10cSrcweir { 1157*cdf0e10cSrcweir osl::ClearableMutexGuard aGuard(m_aMutex); 1158*cdf0e10cSrcweir rtl::Reference< UpdateHandler > aUpdateHandler(getUpdateHandler()); 1159*cdf0e10cSrcweir aGuard.clear(); 1160*cdf0e10cSrcweir 1161*cdf0e10cSrcweir aUpdateHandler->setErrorMessage(rErrorMessage); 1162*cdf0e10cSrcweir setUIState(UPDATESTATE_ERROR_DOWNLOADING); 1163*cdf0e10cSrcweir } 1164*cdf0e10cSrcweir 1165*cdf0e10cSrcweir //------------------------------------------------------------------------------ 1166*cdf0e10cSrcweir 1167*cdf0e10cSrcweir void 1168*cdf0e10cSrcweir UpdateCheck::downloadProgressAt(sal_Int8 nPercent) 1169*cdf0e10cSrcweir { 1170*cdf0e10cSrcweir osl::ClearableMutexGuard aGuard(m_aMutex); 1171*cdf0e10cSrcweir rtl::Reference< UpdateHandler > aUpdateHandler(getUpdateHandler()); 1172*cdf0e10cSrcweir aGuard.clear(); 1173*cdf0e10cSrcweir 1174*cdf0e10cSrcweir aUpdateHandler->setProgress(nPercent); 1175*cdf0e10cSrcweir setUIState(UPDATESTATE_DOWNLOADING); 1176*cdf0e10cSrcweir } 1177*cdf0e10cSrcweir 1178*cdf0e10cSrcweir //------------------------------------------------------------------------------ 1179*cdf0e10cSrcweir 1180*cdf0e10cSrcweir void 1181*cdf0e10cSrcweir UpdateCheck::downloadStarted(const rtl::OUString& rLocalFileName, sal_Int64 nFileSize) 1182*cdf0e10cSrcweir { 1183*cdf0e10cSrcweir if ( nFileSize > 0 ) 1184*cdf0e10cSrcweir { 1185*cdf0e10cSrcweir osl::MutexGuard aGuard(m_aMutex); 1186*cdf0e10cSrcweir 1187*cdf0e10cSrcweir rtl::Reference< UpdateCheckConfig > aModel(UpdateCheckConfig::get(m_xContext)); 1188*cdf0e10cSrcweir aModel->storeLocalFileName(rLocalFileName, nFileSize); 1189*cdf0e10cSrcweir 1190*cdf0e10cSrcweir // Bring-up release note for position 1 .. 1191*cdf0e10cSrcweir const rtl::OUString aURL(getReleaseNote(m_aUpdateInfo, 1, aModel->isAutoDownloadEnabled())); 1192*cdf0e10cSrcweir if( aURL.getLength() > 0 ) 1193*cdf0e10cSrcweir showReleaseNote(aURL); 1194*cdf0e10cSrcweir } 1195*cdf0e10cSrcweir } 1196*cdf0e10cSrcweir 1197*cdf0e10cSrcweir //------------------------------------------------------------------------------ 1198*cdf0e10cSrcweir 1199*cdf0e10cSrcweir void 1200*cdf0e10cSrcweir UpdateCheck::downloadFinished(const rtl::OUString& rLocalFileName) 1201*cdf0e10cSrcweir { 1202*cdf0e10cSrcweir osl::ClearableMutexGuard aGuard(m_aMutex); 1203*cdf0e10cSrcweir 1204*cdf0e10cSrcweir // no more retries 1205*cdf0e10cSrcweir m_pThread->terminate(); 1206*cdf0e10cSrcweir 1207*cdf0e10cSrcweir m_aImageName = getImageFromFileName(rLocalFileName); 1208*cdf0e10cSrcweir UpdateInfo aUpdateInfo(m_aUpdateInfo); 1209*cdf0e10cSrcweir 1210*cdf0e10cSrcweir aGuard.clear(); 1211*cdf0e10cSrcweir setUIState(UPDATESTATE_DOWNLOAD_AVAIL); 1212*cdf0e10cSrcweir 1213*cdf0e10cSrcweir // Bring-up release note for position 2 .. 1214*cdf0e10cSrcweir rtl::Reference< UpdateCheckConfig > rModel = UpdateCheckConfig::get( m_xContext ); 1215*cdf0e10cSrcweir const rtl::OUString aURL(getReleaseNote(aUpdateInfo, 2, rModel->isAutoDownloadEnabled())); 1216*cdf0e10cSrcweir if( aURL.getLength() > 0 ) 1217*cdf0e10cSrcweir showReleaseNote(aURL); 1218*cdf0e10cSrcweir } 1219*cdf0e10cSrcweir 1220*cdf0e10cSrcweir //------------------------------------------------------------------------------ 1221*cdf0e10cSrcweir 1222*cdf0e10cSrcweir void 1223*cdf0e10cSrcweir UpdateCheck::cancelDownload() 1224*cdf0e10cSrcweir { 1225*cdf0e10cSrcweir shutdownThread(true); 1226*cdf0e10cSrcweir 1227*cdf0e10cSrcweir osl::MutexGuard aGuard(m_aMutex); 1228*cdf0e10cSrcweir enableDownload(false); 1229*cdf0e10cSrcweir 1230*cdf0e10cSrcweir rtl::Reference< UpdateCheckConfig > rModel = UpdateCheckConfig::get(m_xContext); 1231*cdf0e10cSrcweir 1232*cdf0e10cSrcweir rtl::OUString aLocalFile(rModel->getLocalFileName()); 1233*cdf0e10cSrcweir rModel->clearLocalFileName(); 1234*cdf0e10cSrcweir rModel->storeDownloadPaused(false); 1235*cdf0e10cSrcweir 1236*cdf0e10cSrcweir if( isObsoleteUpdateInfo(rModel->getUpdateEntryVersion()) ) 1237*cdf0e10cSrcweir { 1238*cdf0e10cSrcweir rModel->clearUpdateFound(); // This wasn't done during init yet .. 1239*cdf0e10cSrcweir m_aUpdateInfo = UpdateInfo(); 1240*cdf0e10cSrcweir } 1241*cdf0e10cSrcweir 1242*cdf0e10cSrcweir /*oslFileError rc =*/ osl_removeFile(aLocalFile.pData); 1243*cdf0e10cSrcweir // FIXME: error handling .. 1244*cdf0e10cSrcweir 1245*cdf0e10cSrcweir } 1246*cdf0e10cSrcweir 1247*cdf0e10cSrcweir //------------------------------------------------------------------------------ 1248*cdf0e10cSrcweir 1249*cdf0e10cSrcweir void 1250*cdf0e10cSrcweir UpdateCheck::showDialog(bool forceCheck) 1251*cdf0e10cSrcweir { 1252*cdf0e10cSrcweir osl::ResettableMutexGuard aGuard(m_aMutex); 1253*cdf0e10cSrcweir 1254*cdf0e10cSrcweir bool update_found = m_aUpdateInfo.BuildId.getLength() > 0; 1255*cdf0e10cSrcweir bool bSetUIState = ! m_aUpdateHandler.is(); 1256*cdf0e10cSrcweir 1257*cdf0e10cSrcweir UpdateState eDialogState = UPDATESTATES_COUNT; 1258*cdf0e10cSrcweir 1259*cdf0e10cSrcweir switch( m_eState ) 1260*cdf0e10cSrcweir { 1261*cdf0e10cSrcweir case DISABLED: 1262*cdf0e10cSrcweir case CHECK_SCHEDULED: 1263*cdf0e10cSrcweir if( forceCheck || ! update_found ) // Run check when forced or if we did not find an update yet 1264*cdf0e10cSrcweir { 1265*cdf0e10cSrcweir eDialogState = UPDATESTATE_CHECKING; 1266*cdf0e10cSrcweir bSetUIState = true; 1267*cdf0e10cSrcweir } 1268*cdf0e10cSrcweir else if(m_aUpdateInfo.Sources[0].IsDirect) 1269*cdf0e10cSrcweir eDialogState = UPDATESTATE_UPDATE_AVAIL; 1270*cdf0e10cSrcweir else 1271*cdf0e10cSrcweir eDialogState = UPDATESTATE_UPDATE_NO_DOWNLOAD; 1272*cdf0e10cSrcweir break; 1273*cdf0e10cSrcweir 1274*cdf0e10cSrcweir case DOWNLOADING: 1275*cdf0e10cSrcweir eDialogState = UPDATESTATE_DOWNLOADING; 1276*cdf0e10cSrcweir break; 1277*cdf0e10cSrcweir 1278*cdf0e10cSrcweir case DOWNLOAD_PAUSED: 1279*cdf0e10cSrcweir eDialogState = UPDATESTATE_DOWNLOAD_PAUSED; 1280*cdf0e10cSrcweir break; 1281*cdf0e10cSrcweir 1282*cdf0e10cSrcweir case NOT_INITIALIZED: 1283*cdf0e10cSrcweir OSL_ASSERT( false ); 1284*cdf0e10cSrcweir break; 1285*cdf0e10cSrcweir } 1286*cdf0e10cSrcweir 1287*cdf0e10cSrcweir if( bSetUIState ) 1288*cdf0e10cSrcweir { 1289*cdf0e10cSrcweir aGuard.clear(); 1290*cdf0e10cSrcweir setUIState(eDialogState, true); // suppress bubble as Dialog will be visible soon 1291*cdf0e10cSrcweir aGuard.reset(); 1292*cdf0e10cSrcweir } 1293*cdf0e10cSrcweir 1294*cdf0e10cSrcweir getUpdateHandler()->setVisible(true); 1295*cdf0e10cSrcweir 1296*cdf0e10cSrcweir // Run check in separate thread .. 1297*cdf0e10cSrcweir if( UPDATESTATE_CHECKING == eDialogState ) 1298*cdf0e10cSrcweir { 1299*cdf0e10cSrcweir if( DISABLED == m_eState ) 1300*cdf0e10cSrcweir { 1301*cdf0e10cSrcweir // destructs itself when done, not cancellable for now .. 1302*cdf0e10cSrcweir new ManualUpdateCheckThread(m_aCondition, m_xContext); 1303*cdf0e10cSrcweir } 1304*cdf0e10cSrcweir 1305*cdf0e10cSrcweir m_aCondition.set(); 1306*cdf0e10cSrcweir } 1307*cdf0e10cSrcweir } 1308*cdf0e10cSrcweir 1309*cdf0e10cSrcweir //------------------------------------------------------------------------------ 1310*cdf0e10cSrcweir 1311*cdf0e10cSrcweir void 1312*cdf0e10cSrcweir UpdateCheck::setUpdateInfo(const UpdateInfo& aInfo) 1313*cdf0e10cSrcweir { 1314*cdf0e10cSrcweir osl::ClearableMutexGuard aGuard(m_aMutex); 1315*cdf0e10cSrcweir 1316*cdf0e10cSrcweir bool bSuppressBubble = (sal_True == aInfo.BuildId.equals(m_aUpdateInfo.BuildId)); 1317*cdf0e10cSrcweir m_aUpdateInfo = aInfo; 1318*cdf0e10cSrcweir 1319*cdf0e10cSrcweir OSL_ASSERT(DISABLED == m_eState || CHECK_SCHEDULED == m_eState); 1320*cdf0e10cSrcweir 1321*cdf0e10cSrcweir // Ignore leading non direct download if we get direct ones 1322*cdf0e10cSrcweir std::vector< DownloadSource >::iterator iter = m_aUpdateInfo.Sources.begin(); 1323*cdf0e10cSrcweir while( iter != m_aUpdateInfo.Sources.end() ) 1324*cdf0e10cSrcweir { 1325*cdf0e10cSrcweir if( iter->IsDirect ) 1326*cdf0e10cSrcweir break; 1327*cdf0e10cSrcweir 1328*cdf0e10cSrcweir ++iter; 1329*cdf0e10cSrcweir } 1330*cdf0e10cSrcweir 1331*cdf0e10cSrcweir if( (iter != m_aUpdateInfo.Sources.begin()) && 1332*cdf0e10cSrcweir (iter != m_aUpdateInfo.Sources.end()) && 1333*cdf0e10cSrcweir iter->IsDirect ) 1334*cdf0e10cSrcweir { 1335*cdf0e10cSrcweir m_aUpdateInfo.Sources.erase(m_aUpdateInfo.Sources.begin(), --iter); 1336*cdf0e10cSrcweir } 1337*cdf0e10cSrcweir 1338*cdf0e10cSrcweir rtl::Reference< UpdateCheckConfig > rModel = UpdateCheckConfig::get(m_xContext, *this); 1339*cdf0e10cSrcweir OSL_ASSERT( rModel.is() ); 1340*cdf0e10cSrcweir 1341*cdf0e10cSrcweir // Decide whether to use alternate release note pos .. 1342*cdf0e10cSrcweir bool autoDownloadEnabled = rModel->isAutoDownloadEnabled(); 1343*cdf0e10cSrcweir 1344*cdf0e10cSrcweir std::vector< ReleaseNote >::iterator iter2 = m_aUpdateInfo.ReleaseNotes.begin(); 1345*cdf0e10cSrcweir while( iter2 != m_aUpdateInfo.ReleaseNotes.end() ) 1346*cdf0e10cSrcweir { 1347*cdf0e10cSrcweir if( ((1 == iter2->Pos) || (2 == iter2->Pos)) && autoDownloadEnabled && (iter2->URL2.getLength() > 0)) 1348*cdf0e10cSrcweir { 1349*cdf0e10cSrcweir iter2->URL = iter2->URL2; 1350*cdf0e10cSrcweir iter2->URL2 = rtl::OUString(); 1351*cdf0e10cSrcweir iter2->Pos = iter2->Pos2; 1352*cdf0e10cSrcweir iter2->Pos2 = 0; 1353*cdf0e10cSrcweir } 1354*cdf0e10cSrcweir 1355*cdf0e10cSrcweir ++iter2; 1356*cdf0e10cSrcweir } 1357*cdf0e10cSrcweir 1358*cdf0e10cSrcweir // do not move below store/clear .. 1359*cdf0e10cSrcweir rModel->updateLastChecked(); 1360*cdf0e10cSrcweir 1361*cdf0e10cSrcweir UpdateState eUIState; 1362*cdf0e10cSrcweir if( m_aUpdateInfo.Sources.size() > 0 ) 1363*cdf0e10cSrcweir { 1364*cdf0e10cSrcweir rModel->storeUpdateFound(aInfo, getBuildId()); 1365*cdf0e10cSrcweir 1366*cdf0e10cSrcweir if( m_aUpdateInfo.Sources[0].IsDirect ) 1367*cdf0e10cSrcweir { 1368*cdf0e10cSrcweir eUIState = UPDATESTATE_UPDATE_AVAIL; 1369*cdf0e10cSrcweir 1370*cdf0e10cSrcweir if( rModel->isAutoDownloadEnabled() ) 1371*cdf0e10cSrcweir { 1372*cdf0e10cSrcweir shutdownThread(false); 1373*cdf0e10cSrcweir eUIState = UPDATESTATE_DOWNLOADING; 1374*cdf0e10cSrcweir enableDownload(true); 1375*cdf0e10cSrcweir } 1376*cdf0e10cSrcweir } 1377*cdf0e10cSrcweir else 1378*cdf0e10cSrcweir eUIState = UPDATESTATE_UPDATE_NO_DOWNLOAD; 1379*cdf0e10cSrcweir } 1380*cdf0e10cSrcweir else 1381*cdf0e10cSrcweir { 1382*cdf0e10cSrcweir eUIState = UPDATESTATE_NO_UPDATE_AVAIL; 1383*cdf0e10cSrcweir rModel->clearUpdateFound(); 1384*cdf0e10cSrcweir } 1385*cdf0e10cSrcweir 1386*cdf0e10cSrcweir aGuard.clear(); 1387*cdf0e10cSrcweir setUIState(eUIState, bSuppressBubble); 1388*cdf0e10cSrcweir } 1389*cdf0e10cSrcweir 1390*cdf0e10cSrcweir //------------------------------------------------------------------------------ 1391*cdf0e10cSrcweir 1392*cdf0e10cSrcweir void 1393*cdf0e10cSrcweir UpdateCheck::setCheckFailedState() 1394*cdf0e10cSrcweir { 1395*cdf0e10cSrcweir setUIState(UPDATESTATE_ERROR_CHECKING); 1396*cdf0e10cSrcweir } 1397*cdf0e10cSrcweir 1398*cdf0e10cSrcweir //------------------------------------------------------------------------------ 1399*cdf0e10cSrcweir void UpdateCheck::handleMenuBarUI( rtl::Reference< UpdateHandler > rUpdateHandler, 1400*cdf0e10cSrcweir UpdateState& eState, 1401*cdf0e10cSrcweir bool suppressBubble ) 1402*cdf0e10cSrcweir { 1403*cdf0e10cSrcweir uno::Reference<beans::XPropertySet> xMenuBarUI( m_xMenuBarUI ); 1404*cdf0e10cSrcweir 1405*cdf0e10cSrcweir if ( ( UPDATESTATE_NO_UPDATE_AVAIL == eState ) && m_bHasExtensionUpdate ) 1406*cdf0e10cSrcweir eState = UPDATESTATE_EXT_UPD_AVAIL; 1407*cdf0e10cSrcweir 1408*cdf0e10cSrcweir if ( UPDATESTATE_EXT_UPD_AVAIL == eState ) 1409*cdf0e10cSrcweir m_bShowExtUpdDlg = true; 1410*cdf0e10cSrcweir else 1411*cdf0e10cSrcweir m_bShowExtUpdDlg = false; 1412*cdf0e10cSrcweir 1413*cdf0e10cSrcweir if( xMenuBarUI.is() ) 1414*cdf0e10cSrcweir { 1415*cdf0e10cSrcweir if( UPDATESTATE_NO_UPDATE_AVAIL == eState ) 1416*cdf0e10cSrcweir { 1417*cdf0e10cSrcweir xMenuBarUI->setPropertyValue( PROPERTY_SHOW_MENUICON, uno::makeAny(sal_False) ); 1418*cdf0e10cSrcweir } 1419*cdf0e10cSrcweir else 1420*cdf0e10cSrcweir { 1421*cdf0e10cSrcweir xMenuBarUI->setPropertyValue( PROPERTY_TITLE, uno::makeAny(rUpdateHandler->getBubbleTitle(eState)) ); 1422*cdf0e10cSrcweir xMenuBarUI->setPropertyValue( PROPERTY_TEXT, uno::makeAny(rUpdateHandler->getBubbleText(eState)) ); 1423*cdf0e10cSrcweir 1424*cdf0e10cSrcweir if( ! suppressBubble && ( ! rUpdateHandler->isVisible() || rUpdateHandler->isMinimized() ) ) 1425*cdf0e10cSrcweir xMenuBarUI->setPropertyValue( PROPERTY_SHOW_BUBBLE, uno::makeAny( sal_True ) ); 1426*cdf0e10cSrcweir 1427*cdf0e10cSrcweir if( UPDATESTATE_CHECKING != eState ) 1428*cdf0e10cSrcweir xMenuBarUI->setPropertyValue( PROPERTY_SHOW_MENUICON, uno::makeAny(sal_True) ); 1429*cdf0e10cSrcweir } 1430*cdf0e10cSrcweir } 1431*cdf0e10cSrcweir } 1432*cdf0e10cSrcweir 1433*cdf0e10cSrcweir //------------------------------------------------------------------------------ 1434*cdf0e10cSrcweir void UpdateCheck::setUIState(UpdateState eState, bool suppressBubble) 1435*cdf0e10cSrcweir { 1436*cdf0e10cSrcweir osl::ClearableMutexGuard aGuard(m_aMutex); 1437*cdf0e10cSrcweir 1438*cdf0e10cSrcweir if( ! m_xMenuBarUI.is() && 1439*cdf0e10cSrcweir (DISABLED != m_eState) && 1440*cdf0e10cSrcweir ( m_bHasExtensionUpdate || (UPDATESTATE_NO_UPDATE_AVAIL != eState)) && 1441*cdf0e10cSrcweir (UPDATESTATE_CHECKING != eState) && 1442*cdf0e10cSrcweir (UPDATESTATE_ERROR_CHECKING != eState) 1443*cdf0e10cSrcweir ) 1444*cdf0e10cSrcweir { 1445*cdf0e10cSrcweir m_xMenuBarUI = createMenuBarUI(m_xContext, new MenuBarButtonJob(this)); 1446*cdf0e10cSrcweir } 1447*cdf0e10cSrcweir 1448*cdf0e10cSrcweir // Show bubble only when the status has changed 1449*cdf0e10cSrcweir if ( eState == m_eUpdateState ) 1450*cdf0e10cSrcweir suppressBubble = true; 1451*cdf0e10cSrcweir else 1452*cdf0e10cSrcweir m_eUpdateState = eState; 1453*cdf0e10cSrcweir 1454*cdf0e10cSrcweir rtl::Reference<UpdateHandler> aUpdateHandler(getUpdateHandler()); 1455*cdf0e10cSrcweir OSL_ASSERT( aUpdateHandler.is() ); 1456*cdf0e10cSrcweir 1457*cdf0e10cSrcweir UpdateInfo aUpdateInfo(m_aUpdateInfo); 1458*cdf0e10cSrcweir rtl::OUString aImageName(m_aImageName); 1459*cdf0e10cSrcweir 1460*cdf0e10cSrcweir aGuard.clear(); 1461*cdf0e10cSrcweir 1462*cdf0e10cSrcweir handleMenuBarUI( aUpdateHandler, eState, suppressBubble ); 1463*cdf0e10cSrcweir 1464*cdf0e10cSrcweir if( (UPDATESTATE_UPDATE_AVAIL == eState) 1465*cdf0e10cSrcweir || (UPDATESTATE_DOWNLOAD_PAUSED == eState) 1466*cdf0e10cSrcweir || (UPDATESTATE_DOWNLOADING == eState) ) 1467*cdf0e10cSrcweir { 1468*cdf0e10cSrcweir uno::Reference< uno::XComponentContext > xContext(m_xContext); 1469*cdf0e10cSrcweir 1470*cdf0e10cSrcweir rtl::OUString aDownloadDestination = 1471*cdf0e10cSrcweir UpdateCheckConfig::get(xContext, this)->getDownloadDestination(); 1472*cdf0e10cSrcweir 1473*cdf0e10cSrcweir osl_getSystemPathFromFileURL(aDownloadDestination.pData, &aDownloadDestination.pData); 1474*cdf0e10cSrcweir 1475*cdf0e10cSrcweir aUpdateHandler->setDownloadPath(aDownloadDestination); 1476*cdf0e10cSrcweir } 1477*cdf0e10cSrcweir else if( UPDATESTATE_DOWNLOAD_AVAIL == eState ) 1478*cdf0e10cSrcweir { 1479*cdf0e10cSrcweir aUpdateHandler->setDownloadFile(aImageName); 1480*cdf0e10cSrcweir } 1481*cdf0e10cSrcweir 1482*cdf0e10cSrcweir aUpdateHandler->setDescription(aUpdateInfo.Description); 1483*cdf0e10cSrcweir aUpdateHandler->setNextVersion(aUpdateInfo.Version); 1484*cdf0e10cSrcweir aUpdateHandler->setState(eState); 1485*cdf0e10cSrcweir } 1486*cdf0e10cSrcweir 1487*cdf0e10cSrcweir //------------------------------------------------------------------------------ 1488*cdf0e10cSrcweir 1489*cdf0e10cSrcweir UpdateState 1490*cdf0e10cSrcweir UpdateCheck::getUIState(const UpdateInfo& rInfo) 1491*cdf0e10cSrcweir { 1492*cdf0e10cSrcweir UpdateState eUIState = UPDATESTATE_NO_UPDATE_AVAIL; 1493*cdf0e10cSrcweir 1494*cdf0e10cSrcweir if( rInfo.BuildId.getLength() > 0 ) 1495*cdf0e10cSrcweir { 1496*cdf0e10cSrcweir if( rInfo.Sources[0].IsDirect ) 1497*cdf0e10cSrcweir eUIState = UPDATESTATE_UPDATE_AVAIL; 1498*cdf0e10cSrcweir else 1499*cdf0e10cSrcweir eUIState = UPDATESTATE_UPDATE_NO_DOWNLOAD; 1500*cdf0e10cSrcweir } 1501*cdf0e10cSrcweir 1502*cdf0e10cSrcweir return eUIState; 1503*cdf0e10cSrcweir } 1504*cdf0e10cSrcweir 1505*cdf0e10cSrcweir //------------------------------------------------------------------------------ 1506*cdf0e10cSrcweir 1507*cdf0e10cSrcweir void 1508*cdf0e10cSrcweir UpdateCheck::showReleaseNote(const rtl::OUString& rURL) const 1509*cdf0e10cSrcweir { 1510*cdf0e10cSrcweir const uno::Reference< c3s::XSystemShellExecute > xShellExecute( 1511*cdf0e10cSrcweir createService( UNISTRING( "com.sun.star.system.SystemShellExecute" ), m_xContext ), 1512*cdf0e10cSrcweir uno::UNO_QUERY ); 1513*cdf0e10cSrcweir 1514*cdf0e10cSrcweir try { 1515*cdf0e10cSrcweir 1516*cdf0e10cSrcweir if( xShellExecute.is() ) 1517*cdf0e10cSrcweir xShellExecute->execute(rURL, rtl::OUString(), c3s::SystemShellExecuteFlags::DEFAULTS); 1518*cdf0e10cSrcweir } catch(c3s::SystemShellExecuteException&) { 1519*cdf0e10cSrcweir } 1520*cdf0e10cSrcweir } 1521*cdf0e10cSrcweir 1522*cdf0e10cSrcweir //------------------------------------------------------------------------------ 1523*cdf0e10cSrcweir 1524*cdf0e10cSrcweir bool 1525*cdf0e10cSrcweir UpdateCheck::storeReleaseNote(sal_Int8 nNum, const rtl::OUString &rURL) 1526*cdf0e10cSrcweir { 1527*cdf0e10cSrcweir osl::FileBase::RC rc; 1528*cdf0e10cSrcweir rtl::OUString aTargetDir( UpdateCheckConfig::getAllUsersDirectory() + UNISTRING( "/sun" ) ); 1529*cdf0e10cSrcweir 1530*cdf0e10cSrcweir rc = osl::Directory::createPath( aTargetDir ); 1531*cdf0e10cSrcweir 1532*cdf0e10cSrcweir rtl::OUString aFileName = UNISTRING("releasenote") + 1533*cdf0e10cSrcweir rtl::OUString::valueOf( (sal_Int32) nNum ) + 1534*cdf0e10cSrcweir UNISTRING(".url"); 1535*cdf0e10cSrcweir 1536*cdf0e10cSrcweir rtl::OUString aFilePath; 1537*cdf0e10cSrcweir rc = osl::FileBase::getAbsoluteFileURL( aTargetDir, aFileName, aFilePath ); 1538*cdf0e10cSrcweir if ( rc != osl::FileBase::E_None ) return false; 1539*cdf0e10cSrcweir 1540*cdf0e10cSrcweir rc = osl::File::remove( aFilePath ); 1541*cdf0e10cSrcweir 1542*cdf0e10cSrcweir // don't store empty release notes, but delete old ones 1543*cdf0e10cSrcweir if ( rURL.getLength() == 0 ) 1544*cdf0e10cSrcweir return true; 1545*cdf0e10cSrcweir 1546*cdf0e10cSrcweir osl::File aFile( aFilePath ); 1547*cdf0e10cSrcweir rc = aFile.open( OpenFlag_Write | OpenFlag_Create ); 1548*cdf0e10cSrcweir 1549*cdf0e10cSrcweir if ( rc != osl::FileBase::E_None ) return false; 1550*cdf0e10cSrcweir 1551*cdf0e10cSrcweir rtl::OString aLineBuf("[InternetShortcut]\r\n"); 1552*cdf0e10cSrcweir sal_uInt64 nWritten = 0; 1553*cdf0e10cSrcweir 1554*cdf0e10cSrcweir rtl::OUString aURL( rURL ); 1555*cdf0e10cSrcweir #ifdef WNT 1556*cdf0e10cSrcweir rc = aFile.write( aLineBuf.getStr(), aLineBuf.getLength(), nWritten ); 1557*cdf0e10cSrcweir if ( rc != osl::FileBase::E_None ) return false; 1558*cdf0e10cSrcweir aURL = UNISTRING("URL=") + rURL; 1559*cdf0e10cSrcweir #endif 1560*cdf0e10cSrcweir aLineBuf = rtl::OUStringToOString( aURL, RTL_TEXTENCODING_UTF8 ); 1561*cdf0e10cSrcweir rc = aFile.write( aLineBuf.getStr(), aLineBuf.getLength(), nWritten ); 1562*cdf0e10cSrcweir if ( rc != osl::FileBase::E_None ) return false; 1563*cdf0e10cSrcweir 1564*cdf0e10cSrcweir aFile.close(); 1565*cdf0e10cSrcweir return true; 1566*cdf0e10cSrcweir } 1567*cdf0e10cSrcweir 1568*cdf0e10cSrcweir //------------------------------------------------------------------------------ 1569*cdf0e10cSrcweir void UpdateCheck::showExtensionDialog() 1570*cdf0e10cSrcweir { 1571*cdf0e10cSrcweir rtl::OUString sServiceName = UNISTRING("com.sun.star.deployment.ui.PackageManagerDialog"); 1572*cdf0e10cSrcweir rtl::OUString sArguments = UNISTRING("SHOW_UPDATE_DIALOG"); 1573*cdf0e10cSrcweir uno::Reference< uno::XInterface > xService; 1574*cdf0e10cSrcweir 1575*cdf0e10cSrcweir if( ! m_xContext.is() ) 1576*cdf0e10cSrcweir throw uno::RuntimeException( 1577*cdf0e10cSrcweir UNISTRING( "UpdateCheck::showExtensionDialog(): empty component context" ), uno::Reference< uno::XInterface > () ); 1578*cdf0e10cSrcweir 1579*cdf0e10cSrcweir uno::Reference< lang::XMultiComponentFactory > xServiceManager( m_xContext->getServiceManager() ); 1580*cdf0e10cSrcweir if( !xServiceManager.is() ) 1581*cdf0e10cSrcweir throw uno::RuntimeException( 1582*cdf0e10cSrcweir UNISTRING( "UpdateCheck::showExtensionDialog(): unable to obtain service manager from component context" ), uno::Reference< uno::XInterface > () ); 1583*cdf0e10cSrcweir 1584*cdf0e10cSrcweir xService = xServiceManager->createInstanceWithContext( sServiceName, m_xContext ); 1585*cdf0e10cSrcweir uno::Reference< task::XJobExecutor > xExecuteable( xService, uno::UNO_QUERY ); 1586*cdf0e10cSrcweir if ( xExecuteable.is() ) 1587*cdf0e10cSrcweir xExecuteable->trigger( sArguments ); 1588*cdf0e10cSrcweir } 1589*cdf0e10cSrcweir 1590*cdf0e10cSrcweir //------------------------------------------------------------------------------ 1591*cdf0e10cSrcweir 1592*cdf0e10cSrcweir rtl::Reference<UpdateHandler> 1593*cdf0e10cSrcweir UpdateCheck::getUpdateHandler() 1594*cdf0e10cSrcweir { 1595*cdf0e10cSrcweir osl::MutexGuard aGuard(m_aMutex); 1596*cdf0e10cSrcweir 1597*cdf0e10cSrcweir if( ! m_aUpdateHandler.is() ) 1598*cdf0e10cSrcweir m_aUpdateHandler = new UpdateHandler(m_xContext, this); 1599*cdf0e10cSrcweir 1600*cdf0e10cSrcweir return m_aUpdateHandler; 1601*cdf0e10cSrcweir } 1602*cdf0e10cSrcweir 1603*cdf0e10cSrcweir //------------------------------------------------------------------------------ 1604*cdf0e10cSrcweir 1605*cdf0e10cSrcweir uno::Reference< task::XInteractionHandler > 1606*cdf0e10cSrcweir UpdateCheck::getInteractionHandler() const 1607*cdf0e10cSrcweir { 1608*cdf0e10cSrcweir osl::MutexGuard aGuard(m_aMutex); 1609*cdf0e10cSrcweir 1610*cdf0e10cSrcweir uno::Reference< task::XInteractionHandler > xHandler; 1611*cdf0e10cSrcweir 1612*cdf0e10cSrcweir if( m_aUpdateHandler.is() && m_aUpdateHandler->isVisible() ) 1613*cdf0e10cSrcweir xHandler = m_aUpdateHandler.get(); 1614*cdf0e10cSrcweir 1615*cdf0e10cSrcweir return xHandler; 1616*cdf0e10cSrcweir } 1617*cdf0e10cSrcweir 1618*cdf0e10cSrcweir //------------------------------------------------------------------------------ 1619*cdf0e10cSrcweir 1620*cdf0e10cSrcweir uno::Reference< uno::XInterface > 1621*cdf0e10cSrcweir UpdateCheck::createService(const rtl::OUString& rServiceName, 1622*cdf0e10cSrcweir const uno::Reference<uno::XComponentContext>& xContext) 1623*cdf0e10cSrcweir { 1624*cdf0e10cSrcweir if( !xContext.is() ) 1625*cdf0e10cSrcweir throw uno::RuntimeException( 1626*cdf0e10cSrcweir UNISTRING( "UpdateCheckConfig: empty component context" ), 1627*cdf0e10cSrcweir uno::Reference< uno::XInterface >() ); 1628*cdf0e10cSrcweir 1629*cdf0e10cSrcweir const uno::Reference< lang::XMultiComponentFactory > xServiceManager(xContext->getServiceManager()); 1630*cdf0e10cSrcweir 1631*cdf0e10cSrcweir if( !xServiceManager.is() ) 1632*cdf0e10cSrcweir throw uno::RuntimeException( 1633*cdf0e10cSrcweir UNISTRING( "UpdateCheckConfig: unable to obtain service manager from component context" ), 1634*cdf0e10cSrcweir uno::Reference< uno::XInterface >() ); 1635*cdf0e10cSrcweir 1636*cdf0e10cSrcweir return xServiceManager->createInstanceWithContext(rServiceName, xContext); 1637*cdf0e10cSrcweir } 1638*cdf0e10cSrcweir 1639*cdf0e10cSrcweir //------------------------------------------------------------------------------ 1640*cdf0e10cSrcweir 1641*cdf0e10cSrcweir bool 1642*cdf0e10cSrcweir UpdateCheck::isDialogShowing() const 1643*cdf0e10cSrcweir { 1644*cdf0e10cSrcweir osl::MutexGuard aGuard(m_aMutex); 1645*cdf0e10cSrcweir return sal_True == m_aUpdateHandler.is() && m_aUpdateHandler->isVisible(); 1646*cdf0e10cSrcweir }; 1647*cdf0e10cSrcweir 1648*cdf0e10cSrcweir //------------------------------------------------------------------------------ 1649*cdf0e10cSrcweir 1650*cdf0e10cSrcweir void 1651*cdf0e10cSrcweir UpdateCheck::autoCheckStatusChanged(bool enabled) 1652*cdf0e10cSrcweir { 1653*cdf0e10cSrcweir osl::ClearableMutexGuard aGuard(m_aMutex); 1654*cdf0e10cSrcweir 1655*cdf0e10cSrcweir if( (CHECK_SCHEDULED == m_eState) && !enabled ) 1656*cdf0e10cSrcweir shutdownThread(false); 1657*cdf0e10cSrcweir 1658*cdf0e10cSrcweir if( (DISABLED == m_eState) || (CHECK_SCHEDULED == m_eState) ) 1659*cdf0e10cSrcweir { 1660*cdf0e10cSrcweir enableAutoCheck(enabled); 1661*cdf0e10cSrcweir UpdateState eState = getUIState(m_aUpdateInfo); 1662*cdf0e10cSrcweir aGuard.clear(); 1663*cdf0e10cSrcweir setUIState(eState); 1664*cdf0e10cSrcweir } 1665*cdf0e10cSrcweir }; 1666*cdf0e10cSrcweir 1667*cdf0e10cSrcweir //------------------------------------------------------------------------------ 1668*cdf0e10cSrcweir 1669*cdf0e10cSrcweir void 1670*cdf0e10cSrcweir UpdateCheck::autoCheckIntervalChanged() 1671*cdf0e10cSrcweir { 1672*cdf0e10cSrcweir // just wake-up 1673*cdf0e10cSrcweir m_aCondition.set(); 1674*cdf0e10cSrcweir }; 1675*cdf0e10cSrcweir 1676*cdf0e10cSrcweir //------------------------------------------------------------------------------ 1677*cdf0e10cSrcweir 1678*cdf0e10cSrcweir oslInterlockedCount SAL_CALL 1679*cdf0e10cSrcweir UpdateCheck::acquire() SAL_THROW(()) 1680*cdf0e10cSrcweir { 1681*cdf0e10cSrcweir return ReferenceObject::acquire(); 1682*cdf0e10cSrcweir } 1683*cdf0e10cSrcweir 1684*cdf0e10cSrcweir //------------------------------------------------------------------------------ 1685*cdf0e10cSrcweir 1686*cdf0e10cSrcweir oslInterlockedCount SAL_CALL 1687*cdf0e10cSrcweir UpdateCheck::release() SAL_THROW(()) 1688*cdf0e10cSrcweir { 1689*cdf0e10cSrcweir return ReferenceObject::release(); 1690*cdf0e10cSrcweir } 1691