Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include "osl/file.hxx"
30 : : #include "osl/mutex.hxx"
31 : :
32 : : #include <rtl/bootstrap.hxx>
33 : : #include <rtl/ustring.hxx>
34 : : #include <rtl/logfile.hxx>
35 : : #include "cppuhelper/compbase3.hxx"
36 : :
37 : : #include "vcl/wrkwin.hxx"
38 : : #include "vcl/timer.hxx"
39 : :
40 : : #include <unotools/configmgr.hxx>
41 : : #include "toolkit/helper/vclunohelper.hxx"
42 : :
43 : : #include <comphelper/processfactory.hxx>
44 : : #include <comphelper/sequence.hxx>
45 : : #include <cppuhelper/bootstrap.hxx>
46 : : #include <com/sun/star/ucb/XCommandEnvironment.hpp>
47 : : #include <com/sun/star/beans/XPropertySet.hpp>
48 : : #include <com/sun/star/beans/NamedValue.hpp>
49 : : #include <com/sun/star/configuration/theDefaultProvider.hpp>
50 : : #include "com/sun/star/deployment/XPackage.hpp"
51 : : #include "com/sun/star/deployment/ExtensionManager.hpp"
52 : : #include "com/sun/star/deployment/LicenseException.hpp"
53 : : #include "com/sun/star/deployment/ui/LicenseDialog.hpp"
54 : : #include <com/sun/star/task/XJob.hpp>
55 : : #include <com/sun/star/task/XJobExecutor.hpp>
56 : : #include <com/sun/star/task/XInteractionApprove.hpp>
57 : : #include <com/sun/star/task/XInteractionAbort.hpp>
58 : : #include <com/sun/star/ui/dialogs/XExecutableDialog.hpp>
59 : : #include "com/sun/star/ui/dialogs/ExecutableDialogResults.hpp"
60 : : #include <com/sun/star/util/XChangesBatch.hpp>
61 : :
62 : : #include "app.hxx"
63 : :
64 : : #include "../deployment/inc/dp_misc.h"
65 : :
66 : : using rtl::OUString;
67 : : using namespace desktop;
68 : : using namespace com::sun::star;
69 : :
70 : : #define UNISTRING(s) OUString(s)
71 : :
72 : : namespace
73 : : {
74 : : //For use with XExtensionManager.synchronize
75 : : class SilentCommandEnv
76 : : : public ::cppu::WeakImplHelper3< ucb::XCommandEnvironment,
77 : : task::XInteractionHandler,
78 : : ucb::XProgressHandler >
79 : : {
80 : : Desktop *mpDesktop;
81 : : sal_Int32 mnLevel;
82 : : sal_Int32 mnProgress;
83 : :
84 : : public:
85 : : SilentCommandEnv( Desktop* pDesktop );
86 : : virtual ~SilentCommandEnv();
87 : :
88 : : // XCommandEnvironment
89 : : virtual uno::Reference<task::XInteractionHandler > SAL_CALL
90 : : getInteractionHandler() throw (uno::RuntimeException);
91 : : virtual uno::Reference<ucb::XProgressHandler >
92 : : SAL_CALL getProgressHandler() throw (uno::RuntimeException);
93 : :
94 : : // XInteractionHandler
95 : : virtual void SAL_CALL handle(
96 : : uno::Reference<task::XInteractionRequest > const & xRequest )
97 : : throw (uno::RuntimeException);
98 : :
99 : : // XProgressHandler
100 : : virtual void SAL_CALL push( uno::Any const & Status )
101 : : throw (uno::RuntimeException);
102 : : virtual void SAL_CALL update( uno::Any const & Status )
103 : : throw (uno::RuntimeException);
104 : : virtual void SAL_CALL pop() throw (uno::RuntimeException);
105 : : };
106 : :
107 : : //-----------------------------------------------------------------------------
108 : 158 : SilentCommandEnv::SilentCommandEnv( Desktop* pDesktop )
109 : : {
110 : 158 : mpDesktop = pDesktop;
111 : 158 : mnLevel = 0;
112 : 158 : mnProgress = 25;
113 : 158 : }
114 : :
115 : : //-----------------------------------------------------------------------------
116 : 158 : SilentCommandEnv::~SilentCommandEnv()
117 : : {
118 [ + - ]: 158 : mpDesktop->SetSplashScreenText( OUString() );
119 [ - + ]: 316 : }
120 : :
121 : : //-----------------------------------------------------------------------------
122 : 680 : Reference<task::XInteractionHandler> SilentCommandEnv::getInteractionHandler()
123 : : throw (uno::RuntimeException)
124 : : {
125 : 680 : return this;
126 : : }
127 : :
128 : : //-----------------------------------------------------------------------------
129 : 3222 : Reference<ucb::XProgressHandler> SilentCommandEnv::getProgressHandler()
130 : : throw (uno::RuntimeException)
131 : : {
132 : 3222 : return this;
133 : : }
134 : :
135 : : //-----------------------------------------------------------------------------
136 : : // XInteractionHandler
137 : 0 : void SilentCommandEnv::handle( Reference< task::XInteractionRequest> const & xRequest )
138 : : throw (uno::RuntimeException)
139 : : {
140 [ # # ]: 0 : deployment::LicenseException licExc;
141 : :
142 [ # # ][ # # ]: 0 : uno::Any request( xRequest->getRequest() );
143 : 0 : bool bApprove = true;
144 : :
145 [ # # ][ # # ]: 0 : if ( request >>= licExc )
146 : : {
147 [ # # ][ # # ]: 0 : uno::Reference< uno::XComponentContext > xContext = comphelper_getProcessComponentContext();
148 : : uno::Reference< ui::dialogs::XExecutableDialog > xDialog(
149 : : deployment::ui::LicenseDialog::create(
150 : : xContext, VCLUnoHelper::GetInterface( NULL ),
151 [ # # ][ # # ]: 0 : licExc.ExtensionName, licExc.Text ) );
152 [ # # ][ # # ]: 0 : sal_Int16 res = xDialog->execute();
153 [ # # ]: 0 : if ( res == ui::dialogs::ExecutableDialogResults::CANCEL )
154 : 0 : bApprove = false;
155 [ # # ]: 0 : else if ( res == ui::dialogs::ExecutableDialogResults::OK )
156 : 0 : bApprove = true;
157 : : else
158 : : {
159 : : OSL_ASSERT(0);
160 : 0 : }
161 : : }
162 : :
163 : : // We approve everything here
164 [ # # ][ # # ]: 0 : uno::Sequence< Reference< task::XInteractionContinuation > > conts( xRequest->getContinuations() );
165 : 0 : Reference< task::XInteractionContinuation > const * pConts = conts.getConstArray();
166 : 0 : sal_Int32 len = conts.getLength();
167 : :
168 [ # # ]: 0 : for ( sal_Int32 pos = 0; pos < len; ++pos )
169 : : {
170 [ # # ]: 0 : if ( bApprove )
171 : : {
172 [ # # ]: 0 : uno::Reference< task::XInteractionApprove > xInteractionApprove( pConts[ pos ], uno::UNO_QUERY );
173 [ # # ]: 0 : if ( xInteractionApprove.is() )
174 [ # # ][ # # ]: 0 : xInteractionApprove->select();
175 : : }
176 : : else
177 : : {
178 [ # # ]: 0 : uno::Reference< task::XInteractionAbort > xInteractionAbort( pConts[ pos ], uno::UNO_QUERY );
179 [ # # ]: 0 : if ( xInteractionAbort.is() )
180 [ # # ][ # # ]: 0 : xInteractionAbort->select();
181 : : }
182 [ # # ][ # # ]: 0 : }
183 : 0 : }
184 : :
185 : : //-----------------------------------------------------------------------------
186 : : // XProgressHandler
187 : 3100 : void SilentCommandEnv::push( uno::Any const & rStatus )
188 : : throw (uno::RuntimeException)
189 : : {
190 : 3100 : OUString sText;
191 : 3100 : mnLevel += 1;
192 : :
193 [ + - ][ + - ]: 3100 : if ( rStatus.hasValue() && ( rStatus >>= sText) )
[ + - ]
194 : : {
195 [ + + ]: 3100 : if ( mnLevel <= 3 )
196 [ + - ]: 620 : mpDesktop->SetSplashScreenText( sText );
197 : : else
198 [ + - ]: 2480 : mpDesktop->SetSplashScreenProgress( ++mnProgress );
199 : 3100 : }
200 : 3100 : }
201 : :
202 : : //-----------------------------------------------------------------------------
203 : 124 : void SilentCommandEnv::update( uno::Any const & rStatus )
204 : : throw (uno::RuntimeException)
205 : : {
206 : 124 : OUString sText;
207 [ + - ][ + - ]: 124 : if ( rStatus.hasValue() && ( rStatus >>= sText) )
[ + - ]
208 : : {
209 [ + - ]: 124 : mpDesktop->SetSplashScreenText( sText );
210 : 124 : }
211 : 124 : }
212 : :
213 : : //-----------------------------------------------------------------------------
214 : 3100 : void SilentCommandEnv::pop() throw (uno::RuntimeException)
215 : : {
216 : 3100 : mnLevel -= 1;
217 : 3100 : }
218 : :
219 : : } // end namespace
220 : :
221 : :
222 : : static const char aAccessSrvc[] = "com.sun.star.configuration.ConfigurationUpdateAccess";
223 : :
224 : 0 : static sal_Int16 impl_showExtensionDialog( uno::Reference< uno::XComponentContext > &xContext )
225 : : {
226 : 0 : rtl::OUString sServiceName = UNISTRING("com.sun.star.deployment.ui.UpdateRequiredDialog");
227 : 0 : uno::Reference< uno::XInterface > xService;
228 : 0 : sal_Int16 nRet = 0;
229 : :
230 [ # # ][ # # ]: 0 : uno::Reference< lang::XMultiComponentFactory > xServiceManager( xContext->getServiceManager() );
231 [ # # ]: 0 : if( !xServiceManager.is() )
232 : : throw uno::RuntimeException(
233 [ # # ]: 0 : UNISTRING( "impl_showExtensionDialog(): unable to obtain service manager from component context" ), uno::Reference< uno::XInterface > () );
234 : :
235 [ # # ][ # # ]: 0 : xService = xServiceManager->createInstanceWithContext( sServiceName, xContext );
[ # # ]
236 [ # # ]: 0 : uno::Reference< ui::dialogs::XExecutableDialog > xExecuteable( xService, uno::UNO_QUERY );
237 [ # # ]: 0 : if ( xExecuteable.is() )
238 [ # # ][ # # ]: 0 : nRet = xExecuteable->execute();
239 : :
240 : 0 : return nRet;
241 : : }
242 : :
243 : : //------------------------------------------------------------------------------
244 : : // Check dependencies of all packages
245 : : //------------------------------------------------------------------------------
246 : 62 : static bool impl_checkDependencies( const uno::Reference< uno::XComponentContext > &xContext )
247 : : {
248 [ + - ]: 62 : uno::Sequence< uno::Sequence< uno::Reference< deployment::XPackage > > > xAllPackages;
249 [ + - ]: 62 : uno::Reference< deployment::XExtensionManager > xExtensionManager = deployment::ExtensionManager::get( xContext );
250 : :
251 [ - + ]: 62 : if ( !xExtensionManager.is() )
252 : : {
253 : : OSL_FAIL( "Could not get the Extension Manager!" );
254 : 0 : return true;
255 : : }
256 : :
257 : : try {
258 [ + - ]: 62 : xAllPackages = xExtensionManager->getAllExtensions( uno::Reference< task::XAbortChannel >(),
259 [ + - ][ + - ]: 62 : uno::Reference< ucb::XCommandEnvironment >() );
[ + - ]
260 : : }
261 [ # # ]: 0 : catch ( const deployment::DeploymentException & ) { return true; }
262 [ # # ]: 0 : catch ( const ucb::CommandFailedException & ) { return true; }
263 [ # # ]: 0 : catch ( const ucb::CommandAbortedException & ) { return true; }
264 [ # # # # : 0 : catch ( const lang::IllegalArgumentException & e ) {
# ]
265 [ # # ]: 0 : throw uno::RuntimeException( e.Message, e.Context );
266 : : }
267 : :
268 : 62 : sal_Int32 nMax = 2;
269 : : #ifdef DEBUG
270 : : nMax = 3;
271 : : #endif
272 : :
273 [ + + ]: 558 : for ( sal_Int32 i = 0; i < xAllPackages.getLength(); ++i )
274 : : {
275 [ + - ][ + - ]: 496 : uno::Sequence< uno::Reference< deployment::XPackage > > xPackageList = xAllPackages[i];
276 : :
277 [ + + ][ + - ]: 1488 : for ( sal_Int32 j = 0; (j<nMax) && (j < xPackageList.getLength()); ++j )
[ + + ]
278 : : {
279 [ + - ]: 992 : uno::Reference< deployment::XPackage > xPackage = xPackageList[j];
280 [ - + ]: 992 : if ( xPackage.is() )
281 : : {
282 : 0 : bool bRegistered = false;
283 : : try {
284 [ # # ]: 0 : beans::Optional< beans::Ambiguous< sal_Bool > > option( xPackage->isRegistered( uno::Reference< task::XAbortChannel >(),
285 [ # # ]: 0 : uno::Reference< ucb::XCommandEnvironment >() ) );
286 [ # # ]: 0 : if ( option.IsPresent )
287 : : {
288 : 0 : ::beans::Ambiguous< sal_Bool > const & reg = option.Value;
289 [ # # ]: 0 : if ( reg.IsAmbiguous )
290 : 0 : bRegistered = false;
291 : : else
292 : 0 : bRegistered = reg.Value ? true : false;
293 : : }
294 : : else
295 : 0 : bRegistered = false;
296 : : }
297 [ # # # ]: 0 : catch ( const uno::RuntimeException & ) { throw; }
298 [ # # ]: 0 : catch (const uno::Exception & exc) {
299 : : (void) exc;
300 : : OSL_FAIL( ::rtl::OUStringToOString( exc.Message, RTL_TEXTENCODING_UTF8 ).getStr() );
301 : : }
302 : :
303 [ # # ]: 0 : if ( bRegistered )
304 : : {
305 : 0 : bool bDependenciesValid = false;
306 : : try {
307 [ # # ][ # # ]: 0 : bDependenciesValid = xPackage->checkDependencies( uno::Reference< ucb::XCommandEnvironment >() );
[ # # ]
308 : : }
309 [ # # ]: 0 : catch ( const deployment::DeploymentException & ) {}
310 [ # # ]: 0 : if ( ! bDependenciesValid )
311 : : {
312 : 992 : return false;
313 : : }
314 : : }
315 : : }
316 [ + - ]: 992 : }
317 [ + - ][ + - ]: 496 : }
318 [ + - ]: 62 : return true;
319 : : }
320 : :
321 : : //------------------------------------------------------------------------------
322 : : // resets the 'check needed' flag (needed, if aborted)
323 : : //------------------------------------------------------------------------------
324 : 0 : static void impl_setNeedsCompatCheck()
325 : : {
326 : : try {
327 : : Reference< XMultiServiceFactory > theConfigProvider(
328 : : configuration::theDefaultProvider::get(
329 [ # # ][ # # ]: 0 : comphelper::getProcessComponentContext() ) );
330 : :
331 [ # # ]: 0 : Sequence< Any > theArgs(1);
332 : : beans::NamedValue v( OUString("nodepath"),
333 [ # # ]: 0 : makeAny( OUString("org.openoffice.Setup/Office") ) );
334 [ # # ][ # # ]: 0 : theArgs[0] <<= v;
335 : : Reference< beans::XPropertySet > pset = Reference< beans::XPropertySet >(
336 [ # # ][ # # ]: 0 : theConfigProvider->createInstanceWithArguments( rtl::OUString(aAccessSrvc), theArgs ), UNO_QUERY_THROW );
[ # # ]
337 : :
338 [ # # ]: 0 : Any value = makeAny( OUString("never") );
339 : :
340 [ # # ][ # # ]: 0 : pset->setPropertyValue( OUString("LastCompatibilityCheckID"), value );
341 [ # # ][ # # ]: 0 : Reference< util::XChangesBatch >( pset, UNO_QUERY_THROW )->commitChanges();
[ # # ][ # # ]
[ # # ]
342 : : }
343 : 0 : catch (const Exception&) {}
344 : 0 : }
345 : :
346 : : //------------------------------------------------------------------------------
347 : : // to check if we need checking the dependencies of the extensions again, we compare
348 : : // the build id of the office with the one of the last check
349 : : //------------------------------------------------------------------------------
350 : 158 : static bool impl_needsCompatCheck()
351 : : {
352 : 158 : bool bNeedsCheck = false;
353 : 158 : rtl::OUString aLastCheckBuildID;
354 : 158 : rtl::OUString aCurrentBuildID( UNISTRING( "${$BRAND_BASE_DIR/program/" SAL_CONFIGFILE("version") ":buildid}" ) );
355 : 158 : rtl::Bootstrap::expandMacros( aCurrentBuildID );
356 : :
357 : : try {
358 : : Reference< XMultiServiceFactory > theConfigProvider(
359 : : configuration::theDefaultProvider::get(
360 [ + - ][ + - ]: 158 : comphelper::getProcessComponentContext() ) );
361 : :
362 [ + - ]: 158 : Sequence< Any > theArgs(1);
363 : : beans::NamedValue v( OUString("nodepath"),
364 [ + - ]: 158 : makeAny( OUString("org.openoffice.Setup/Office") ) );
365 [ + - ][ + - ]: 158 : theArgs[0] <<= v;
366 : : Reference< beans::XPropertySet > pset = Reference< beans::XPropertySet >(
367 [ + - ][ + - ]: 158 : theConfigProvider->createInstanceWithArguments( rtl::OUString(aAccessSrvc), theArgs ), UNO_QUERY_THROW );
[ + - ]
368 : :
369 [ + - ][ + - ]: 158 : Any result = pset->getPropertyValue( OUString("LastCompatibilityCheckID") );
370 : :
371 : 158 : result >>= aLastCheckBuildID;
372 [ + + ]: 158 : if ( aLastCheckBuildID != aCurrentBuildID )
373 : : {
374 : 62 : bNeedsCheck = true;
375 [ + - ]: 62 : result <<= aCurrentBuildID;
376 [ + - ][ + - ]: 62 : pset->setPropertyValue( OUString("LastCompatibilityCheckID"), result );
377 [ + - ][ + - ]: 62 : Reference< util::XChangesBatch >( pset, UNO_QUERY_THROW )->commitChanges();
[ + - ]
378 [ + - ][ # # ]: 158 : }
379 : : #ifdef DEBUG
380 : : bNeedsCheck = true;
381 : : #endif
382 : : }
383 [ # # ]: 0 : catch (const com::sun::star::uno::Exception&) {}
384 : :
385 : 158 : return bNeedsCheck;
386 : : }
387 : :
388 : : //------------------------------------------------------------------------------
389 : : // Do we need to check the dependencies of the extensions?
390 : : // When there are unresolved issues, we can't continue with startup
391 : 158 : sal_Bool Desktop::CheckExtensionDependencies()
392 : : {
393 [ + - ][ + + ]: 158 : if (!impl_needsCompatCheck())
394 : : {
395 : 96 : return false;
396 : : }
397 : :
398 [ + - ][ + - ]: 62 : uno::Reference< uno::XComponentContext > xContext = comphelper_getProcessComponentContext();
399 : :
400 [ + - ]: 62 : bool bDependenciesValid = impl_checkDependencies( xContext );
401 : :
402 : 62 : short nRet = 0;
403 : :
404 [ - + ]: 62 : if ( !bDependenciesValid )
405 [ # # ]: 0 : nRet = impl_showExtensionDialog( xContext );
406 : :
407 [ - + ]: 62 : if ( nRet == -1 )
408 : : {
409 [ # # ]: 0 : impl_setNeedsCompatCheck();
410 : 0 : return true;
411 : : }
412 : : else
413 : 158 : return false;
414 : : }
415 : :
416 : 158 : void Desktop::SynchronizeExtensionRepositories()
417 : : {
418 : : RTL_LOGFILE_CONTEXT(aLog,"desktop (jl) ::Desktop::SynchronizeExtensionRepositories");
419 [ + - ][ + - ]: 158 : dp_misc::syncRepositories( new SilentCommandEnv( this ) );
[ + - ]
420 : 158 : }
421 : :
422 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|