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