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 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 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 102 UpdateCheckJob::~UpdateCheckJob() 103 { 104 } 105 106 //------------------------------------------------------------------------------ 107 108 uno::Sequence< rtl::OUString > 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 119 UpdateCheckJob::getImplName() 120 { 121 return UNISTRING( "vnd.sun.UpdateCheck"); 122 } 123 124 125 //------------------------------------------------------------------------------ 126 127 uno::Any 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 //------------------------------------------------------------------------------ 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 200 UpdateCheckJob::getImplementationName() 201 { 202 return getImplName(); 203 } 204 205 //------------------------------------------------------------------------------ 206 207 uno::Sequence< rtl::OUString > SAL_CALL 208 UpdateCheckJob::getSupportedServiceNames() 209 { 210 return getServiceNames(); 211 } 212 213 //------------------------------------------------------------------------------ 214 215 sal_Bool SAL_CALL 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 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 242 void SAL_CALL UpdateCheckJob::queryTermination( lang::EventObject const & ) 243 { 244 } 245 246 //------------------------------------------------------------------------------ 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 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 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 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 * 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