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 65 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 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 109 UpdateCheckJob::~UpdateCheckJob() 110 { 111 } 112 113 //------------------------------------------------------------------------------ 114 115 uno::Sequence< rtl::OUString > 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 126 UpdateCheckJob::getImplName() 127 { 128 return UNISTRING( "vnd.sun.UpdateCheck"); 129 } 130 131 132 //------------------------------------------------------------------------------ 133 134 uno::Any 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 //------------------------------------------------------------------------------ 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 208 UpdateCheckJob::getImplementationName() throw (uno::RuntimeException) 209 { 210 return getImplName(); 211 } 212 213 //------------------------------------------------------------------------------ 214 215 uno::Sequence< rtl::OUString > SAL_CALL 216 UpdateCheckJob::getSupportedServiceNames() throw (uno::RuntimeException) 217 { 218 return getServiceNames(); 219 } 220 221 //------------------------------------------------------------------------------ 222 223 sal_Bool SAL_CALL 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 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 251 void SAL_CALL UpdateCheckJob::queryTermination( lang::EventObject const & ) 252 throw ( frame::TerminationVetoException, uno::RuntimeException ) 253 { 254 } 255 256 //------------------------------------------------------------------------------ 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 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 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 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 * 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