1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_extensions.hxx"
26
27 #include <memory>
28
29 #include "updatecheck.hxx"
30 #include "updatecheckconfig.hxx"
31 #include "updatehdl.hxx"
32 #include "updateprotocol.hxx"
33
34 #include <cppuhelper/implbase3.hxx>
35 #include <cppuhelper/implementationentry.hxx>
36
37 #include "com/sun/star/frame/XDesktop.hpp"
38 #include "com/sun/star/frame/XTerminateListener.hpp"
39 #include <com/sun/star/task/XJob.hpp>
40
41 namespace beans = com::sun::star::beans ;
42 namespace frame = com::sun::star::frame ;
43 namespace lang = com::sun::star::lang ;
44 namespace task = com::sun::star::task ;
45 namespace uno = com::sun::star::uno ;
46
47 #define UNISTRING(s) rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(s))
48
49 namespace
50 {
51
52 class UpdateCheckJob :
53 public ::cppu::WeakImplHelper3< task::XJob, lang::XServiceInfo, frame::XTerminateListener >
54 {
55 virtual ~UpdateCheckJob();
56
57 public:
58
59 UpdateCheckJob(const uno::Reference<uno::XComponentContext>& xContext);
60
61 static uno::Sequence< rtl::OUString > getServiceNames();
62 static rtl::OUString getImplName();
63
64 // Allows runtime exceptions to be thrown by const methods
operator uno::Reference<uno::XInterface>() const65 inline SAL_CALL operator uno::Reference< uno::XInterface > () const
66 { return const_cast< cppu::OWeakObject * > (static_cast< cppu::OWeakObject const * > (this)); };
67
68 // XJob
69 virtual uno::Any SAL_CALL execute(const uno::Sequence<beans::NamedValue>&)
70 throw (lang::IllegalArgumentException, uno::Exception);
71
72 // XServiceInfo
73 virtual rtl::OUString SAL_CALL getImplementationName()
74 throw (uno::RuntimeException);
75 virtual sal_Bool SAL_CALL supportsService(rtl::OUString const & serviceName)
76 throw (uno::RuntimeException);
77 virtual uno::Sequence< rtl::OUString > SAL_CALL getSupportedServiceNames()
78 throw (uno::RuntimeException);
79
80 // XEventListener
81 virtual void SAL_CALL disposing( ::com::sun::star::lang::EventObject const & evt )
82 throw (::com::sun::star::uno::RuntimeException);
83
84 // XTerminateListener
85 virtual void SAL_CALL queryTermination( lang::EventObject const & evt )
86 throw ( frame::TerminationVetoException, uno::RuntimeException );
87 virtual void SAL_CALL notifyTermination( lang::EventObject const & evt )
88 throw ( uno::RuntimeException );
89
90 private:
91 uno::Reference<uno::XComponentContext> m_xContext;
92 uno::Reference< frame::XDesktop > m_xDesktop;
93
94 void handleExtensionUpdates( const uno::Sequence< beans::NamedValue > &rListProp );
95 };
96
97 //------------------------------------------------------------------------------
98
UpdateCheckJob(const uno::Reference<uno::XComponentContext> & xContext)99 UpdateCheckJob::UpdateCheckJob( const uno::Reference<uno::XComponentContext>& xContext ) :
100 m_xContext(xContext)
101 {
102 m_xDesktop.set( xContext->getServiceManager()->createInstanceWithContext( UNISTRING("com.sun.star.frame.Desktop"), xContext ), uno::UNO_QUERY );
103 if ( m_xDesktop.is() )
104 m_xDesktop->addTerminateListener( this );
105 }
106
107 //------------------------------------------------------------------------------
108
~UpdateCheckJob()109 UpdateCheckJob::~UpdateCheckJob()
110 {
111 }
112
113 //------------------------------------------------------------------------------
114
115 uno::Sequence< rtl::OUString >
getServiceNames()116 UpdateCheckJob::getServiceNames()
117 {
118 uno::Sequence< rtl::OUString > aServiceList(1);
119 aServiceList[0] = UNISTRING( "com.sun.star.setup.UpdateCheck");
120 return aServiceList;
121 };
122
123 //------------------------------------------------------------------------------
124
125 rtl::OUString
getImplName()126 UpdateCheckJob::getImplName()
127 {
128 return UNISTRING( "vnd.sun.UpdateCheck");
129 }
130
131
132 //------------------------------------------------------------------------------
133
134 uno::Any
execute(const uno::Sequence<beans::NamedValue> & namedValues)135 UpdateCheckJob::execute(const uno::Sequence<beans::NamedValue>& namedValues)
136 throw (lang::IllegalArgumentException, uno::Exception)
137 {
138 for ( sal_Int32 n=namedValues.getLength(); n-- > 0; )
139 {
140 if ( namedValues[ n ].Name.equalsAscii( "DynamicData" ) )
141 {
142 uno::Sequence<beans::NamedValue> aListProp;
143 if ( namedValues[n].Value >>= aListProp )
144 {
145 for ( sal_Int32 i=aListProp.getLength(); i-- > 0; )
146 {
147 if ( aListProp[ i ].Name.equalsAscii( "updateList" ) )
148 {
149 handleExtensionUpdates( aListProp );
150 return uno::Any();
151 }
152 }
153 }
154 }
155 }
156
157 uno::Sequence<beans::NamedValue> aConfig =
158 getValue< uno::Sequence<beans::NamedValue> > (namedValues, "JobConfig");
159
160 rtl::Reference< UpdateCheck > aController( UpdateCheck::get() );
161 aController->initialize( aConfig, m_xContext );
162 aController->showDialog( true );
163
164 return uno::Any();
165 }
166
167 //------------------------------------------------------------------------------
handleExtensionUpdates(const uno::Sequence<beans::NamedValue> & rListProp)168 void UpdateCheckJob::handleExtensionUpdates( const uno::Sequence< beans::NamedValue > &rListProp )
169 {
170 try {
171 uno::Sequence< uno::Sequence< rtl::OUString > > aList =
172 getValue< uno::Sequence< uno::Sequence< rtl::OUString > > > ( rListProp, "updateList" );
173 bool bPrepareOnly = getValue< bool > ( rListProp, "prepareOnly" );
174
175 // we will first store any new found updates and then check, if there are any
176 // pending updates.
177 storeExtensionUpdateInfos( m_xContext, aList );
178
179 if ( bPrepareOnly )
180 return;
181
182 bool bHasUpdates = checkForPendingUpdates( m_xContext );
183
184 rtl::Reference<UpdateCheck> aController( UpdateCheck::get() );
185 if ( ! aController.is() )
186 return;
187
188 aController->setHasExtensionUpdates( bHasUpdates );
189
190 if ( ! aController->hasOfficeUpdate() )
191 {
192 if ( bHasUpdates )
193 aController->setUIState( UPDATESTATE_EXT_UPD_AVAIL, true );
194 else
195 aController->setUIState( UPDATESTATE_NO_UPDATE_AVAIL, true );
196 }
197 }
198 catch( const uno::Exception& e )
199 {
200 OSL_TRACE( "Caught exception: %s\n thread terminated.\n",
201 rtl::OUStringToOString(e.Message, RTL_TEXTENCODING_UTF8).getStr());
202 }
203 }
204
205 //------------------------------------------------------------------------------
206
207 rtl::OUString SAL_CALL
getImplementationName()208 UpdateCheckJob::getImplementationName() throw (uno::RuntimeException)
209 {
210 return getImplName();
211 }
212
213 //------------------------------------------------------------------------------
214
215 uno::Sequence< rtl::OUString > SAL_CALL
getSupportedServiceNames()216 UpdateCheckJob::getSupportedServiceNames() throw (uno::RuntimeException)
217 {
218 return getServiceNames();
219 }
220
221 //------------------------------------------------------------------------------
222
223 sal_Bool SAL_CALL
supportsService(rtl::OUString const & serviceName)224 UpdateCheckJob::supportsService( rtl::OUString const & serviceName ) throw (uno::RuntimeException)
225 {
226 uno::Sequence< rtl::OUString > aServiceNameList = getServiceNames();
227
228 for( sal_Int32 n=0; n < aServiceNameList.getLength(); n++ )
229 if( aServiceNameList[n].equals(serviceName) )
230 return sal_True;
231
232 return sal_False;
233 }
234
235 //------------------------------------------------------------------------------
236 // XEventListener
disposing(lang::EventObject const & rEvt)237 void SAL_CALL UpdateCheckJob::disposing( lang::EventObject const & rEvt )
238 throw ( uno::RuntimeException )
239 {
240 bool shutDown = ( rEvt.Source == m_xDesktop );
241
242 if ( shutDown && m_xDesktop.is() )
243 {
244 m_xDesktop->removeTerminateListener( this );
245 m_xDesktop.clear();
246 }
247 }
248
249 //------------------------------------------------------------------------------
250 // XTerminateListener
queryTermination(lang::EventObject const &)251 void SAL_CALL UpdateCheckJob::queryTermination( lang::EventObject const & )
252 throw ( frame::TerminationVetoException, uno::RuntimeException )
253 {
254 }
255
256 //------------------------------------------------------------------------------
notifyTermination(lang::EventObject const &)257 void SAL_CALL UpdateCheckJob::notifyTermination( lang::EventObject const & )
258 throw ( uno::RuntimeException )
259 {
260 }
261
262 } // anonymous namespace
263
264 //------------------------------------------------------------------------------
265
266 static uno::Reference<uno::XInterface> SAL_CALL
createJobInstance(const uno::Reference<uno::XComponentContext> & xContext)267 createJobInstance(const uno::Reference<uno::XComponentContext>& xContext)
268 {
269 return *new UpdateCheckJob(xContext);
270 }
271
272 //------------------------------------------------------------------------------
273
274 static uno::Reference<uno::XInterface> SAL_CALL
createConfigInstance(const uno::Reference<uno::XComponentContext> & xContext)275 createConfigInstance(const uno::Reference<uno::XComponentContext>& xContext)
276 {
277 return *UpdateCheckConfig::get(xContext, *UpdateCheck::get());
278 }
279
280 //------------------------------------------------------------------------------
281
282 static const cppu::ImplementationEntry kImplementations_entries[] =
283 {
284 {
285 createJobInstance,
286 UpdateCheckJob::getImplName,
287 UpdateCheckJob::getServiceNames,
288 cppu::createSingleComponentFactory,
289 NULL,
290 0
291 },
292 {
293 createConfigInstance,
294 UpdateCheckConfig::getImplName,
295 UpdateCheckConfig::getServiceNames,
296 cppu::createSingleComponentFactory,
297 NULL,
298 0
299 },
300 { NULL, NULL, NULL, NULL, NULL, 0 }
301 } ;
302
303 //------------------------------------------------------------------------------
304
305 extern "C" void SAL_CALL
component_getImplementationEnvironment(const sal_Char ** aEnvTypeName,uno_Environment **)306 component_getImplementationEnvironment( const sal_Char **aEnvTypeName, uno_Environment **)
307 {
308 *aEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME ;
309 }
310
311 //------------------------------------------------------------------------------
312
313 extern "C" void *
component_getFactory(const sal_Char * pszImplementationName,void * pServiceManager,void * pRegistryKey)314 component_getFactory(const sal_Char *pszImplementationName, void *pServiceManager, void *pRegistryKey)
315 {
316 return cppu::component_getFactoryHelper(
317 pszImplementationName,
318 pServiceManager,
319 pRegistryKey,
320 kImplementations_entries) ;
321 }
322