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
71 // XServiceInfo
72 virtual rtl::OUString SAL_CALL getImplementationName();
73 virtual sal_Bool SAL_CALL supportsService(rtl::OUString const & serviceName);
74 virtual uno::Sequence< rtl::OUString > SAL_CALL getSupportedServiceNames();
75
76 // XEventListener
77 virtual void SAL_CALL disposing( ::com::sun::star::lang::EventObject const & evt );
78
79 // XTerminateListener
80 virtual void SAL_CALL queryTermination( lang::EventObject const & evt );
81 virtual void SAL_CALL notifyTermination( lang::EventObject const & evt );
82
83 private:
84 uno::Reference<uno::XComponentContext> m_xContext;
85 uno::Reference< frame::XDesktop > m_xDesktop;
86
87 void handleExtensionUpdates( const uno::Sequence< beans::NamedValue > &rListProp );
88 };
89
90 //------------------------------------------------------------------------------
91
UpdateCheckJob(const uno::Reference<uno::XComponentContext> & xContext)92 UpdateCheckJob::UpdateCheckJob( const uno::Reference<uno::XComponentContext>& xContext ) :
93 m_xContext(xContext)
94 {
95 m_xDesktop.set( xContext->getServiceManager()->createInstanceWithContext( UNISTRING("com.sun.star.frame.Desktop"), xContext ), uno::UNO_QUERY );
96 if ( m_xDesktop.is() )
97 m_xDesktop->addTerminateListener( this );
98 }
99
100 //------------------------------------------------------------------------------
101
~UpdateCheckJob()102 UpdateCheckJob::~UpdateCheckJob()
103 {
104 }
105
106 //------------------------------------------------------------------------------
107
108 uno::Sequence< rtl::OUString >
getServiceNames()109 UpdateCheckJob::getServiceNames()
110 {
111 uno::Sequence< rtl::OUString > aServiceList(1);
112 aServiceList[0] = UNISTRING( "com.sun.star.setup.UpdateCheck");
113 return aServiceList;
114 };
115
116 //------------------------------------------------------------------------------
117
118 rtl::OUString
getImplName()119 UpdateCheckJob::getImplName()
120 {
121 return UNISTRING( "vnd.sun.UpdateCheck");
122 }
123
124
125 //------------------------------------------------------------------------------
126
127 uno::Any
execute(const uno::Sequence<beans::NamedValue> & namedValues)128 UpdateCheckJob::execute(const uno::Sequence<beans::NamedValue>& namedValues)
129 {
130 for ( sal_Int32 n=namedValues.getLength(); n-- > 0; )
131 {
132 if ( namedValues[ n ].Name.equalsAscii( "DynamicData" ) )
133 {
134 uno::Sequence<beans::NamedValue> aListProp;
135 if ( namedValues[n].Value >>= aListProp )
136 {
137 for ( sal_Int32 i=aListProp.getLength(); i-- > 0; )
138 {
139 if ( aListProp[ i ].Name.equalsAscii( "updateList" ) )
140 {
141 handleExtensionUpdates( aListProp );
142 return uno::Any();
143 }
144 }
145 }
146 }
147 }
148
149 uno::Sequence<beans::NamedValue> aConfig =
150 getValue< uno::Sequence<beans::NamedValue> > (namedValues, "JobConfig");
151
152 rtl::Reference< UpdateCheck > aController( UpdateCheck::get() );
153 aController->initialize( aConfig, m_xContext );
154 aController->showDialog( true );
155
156 return uno::Any();
157 }
158
159 //------------------------------------------------------------------------------
handleExtensionUpdates(const uno::Sequence<beans::NamedValue> & rListProp)160 void UpdateCheckJob::handleExtensionUpdates( const uno::Sequence< beans::NamedValue > &rListProp )
161 {
162 try {
163 uno::Sequence< uno::Sequence< rtl::OUString > > aList =
164 getValue< uno::Sequence< uno::Sequence< rtl::OUString > > > ( rListProp, "updateList" );
165 bool bPrepareOnly = getValue< bool > ( rListProp, "prepareOnly" );
166
167 // we will first store any new found updates and then check, if there are any
168 // pending updates.
169 storeExtensionUpdateInfos( m_xContext, aList );
170
171 if ( bPrepareOnly )
172 return;
173
174 bool bHasUpdates = checkForPendingUpdates( m_xContext );
175
176 rtl::Reference<UpdateCheck> aController( UpdateCheck::get() );
177 if ( ! aController.is() )
178 return;
179
180 aController->setHasExtensionUpdates( bHasUpdates );
181
182 if ( ! aController->hasOfficeUpdate() )
183 {
184 if ( bHasUpdates )
185 aController->setUIState( UPDATESTATE_EXT_UPD_AVAIL, true );
186 else
187 aController->setUIState( UPDATESTATE_NO_UPDATE_AVAIL, true );
188 }
189 }
190 catch( const uno::Exception& e )
191 {
192 OSL_TRACE( "Caught exception: %s\n thread terminated.\n",
193 rtl::OUStringToOString(e.Message, RTL_TEXTENCODING_UTF8).getStr());
194 }
195 }
196
197 //------------------------------------------------------------------------------
198
199 rtl::OUString SAL_CALL
getImplementationName()200 UpdateCheckJob::getImplementationName()
201 {
202 return getImplName();
203 }
204
205 //------------------------------------------------------------------------------
206
207 uno::Sequence< rtl::OUString > SAL_CALL
getSupportedServiceNames()208 UpdateCheckJob::getSupportedServiceNames()
209 {
210 return getServiceNames();
211 }
212
213 //------------------------------------------------------------------------------
214
215 sal_Bool SAL_CALL
supportsService(rtl::OUString const & serviceName)216 UpdateCheckJob::supportsService( rtl::OUString const & serviceName )
217 {
218 uno::Sequence< rtl::OUString > aServiceNameList = getServiceNames();
219
220 for( sal_Int32 n=0; n < aServiceNameList.getLength(); n++ )
221 if( aServiceNameList[n].equals(serviceName) )
222 return sal_True;
223
224 return sal_False;
225 }
226
227 //------------------------------------------------------------------------------
228 // XEventListener
disposing(lang::EventObject const & rEvt)229 void SAL_CALL UpdateCheckJob::disposing( lang::EventObject const & rEvt )
230 {
231 bool shutDown = ( rEvt.Source == m_xDesktop );
232
233 if ( shutDown && m_xDesktop.is() )
234 {
235 m_xDesktop->removeTerminateListener( this );
236 m_xDesktop.clear();
237 }
238 }
239
240 //------------------------------------------------------------------------------
241 // XTerminateListener
queryTermination(lang::EventObject const &)242 void SAL_CALL UpdateCheckJob::queryTermination( lang::EventObject const & )
243 {
244 }
245
246 //------------------------------------------------------------------------------
notifyTermination(lang::EventObject const &)247 void SAL_CALL UpdateCheckJob::notifyTermination( lang::EventObject const & )
248 {
249 }
250
251 } // anonymous namespace
252
253 //------------------------------------------------------------------------------
254
255 static uno::Reference<uno::XInterface> SAL_CALL
createJobInstance(const uno::Reference<uno::XComponentContext> & xContext)256 createJobInstance(const uno::Reference<uno::XComponentContext>& xContext)
257 {
258 return *new UpdateCheckJob(xContext);
259 }
260
261 //------------------------------------------------------------------------------
262
263 static uno::Reference<uno::XInterface> SAL_CALL
createConfigInstance(const uno::Reference<uno::XComponentContext> & xContext)264 createConfigInstance(const uno::Reference<uno::XComponentContext>& xContext)
265 {
266 return *UpdateCheckConfig::get(xContext, *UpdateCheck::get());
267 }
268
269 //------------------------------------------------------------------------------
270
271 static const cppu::ImplementationEntry kImplementations_entries[] =
272 {
273 {
274 createJobInstance,
275 UpdateCheckJob::getImplName,
276 UpdateCheckJob::getServiceNames,
277 cppu::createSingleComponentFactory,
278 NULL,
279 0
280 },
281 {
282 createConfigInstance,
283 UpdateCheckConfig::getImplName,
284 UpdateCheckConfig::getServiceNames,
285 cppu::createSingleComponentFactory,
286 NULL,
287 0
288 },
289 { NULL, NULL, NULL, NULL, NULL, 0 }
290 } ;
291
292 //------------------------------------------------------------------------------
293
294 extern "C" void SAL_CALL
component_getImplementationEnvironment(const sal_Char ** aEnvTypeName,uno_Environment **)295 component_getImplementationEnvironment( const sal_Char **aEnvTypeName, uno_Environment **)
296 {
297 *aEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME ;
298 }
299
300 //------------------------------------------------------------------------------
301
302 extern "C" void *
component_getFactory(const sal_Char * pszImplementationName,void * pServiceManager,void * pRegistryKey)303 component_getFactory(const sal_Char *pszImplementationName, void *pServiceManager, void *pRegistryKey)
304 {
305 return cppu::component_getFactoryHelper(
306 pszImplementationName,
307 pServiceManager,
308 pRegistryKey,
309 kImplementations_entries) ;
310 }
311