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