diff options
-rw-r--r-- | desktop/inc/app.hxx | 4 | ||||
-rw-r--r-- | desktop/source/app/app.cxx | 153 | ||||
-rw-r--r-- | desktop/source/app/check_ext_deps.cxx | 19 | ||||
-rw-r--r-- | desktop/source/deployment/gui/dp_gui_extensioncmdqueue.cxx | 2 | ||||
-rw-r--r-- | desktop/source/deployment/inc/dp_misc.h | 3 | ||||
-rw-r--r-- | desktop/source/deployment/manager/dp_extensionmanager.cxx | 9 | ||||
-rw-r--r-- | desktop/source/deployment/manager/dp_extensionmanager.hxx | 1 | ||||
-rw-r--r-- | desktop/source/deployment/manager/dp_manager.cxx | 22 | ||||
-rw-r--r-- | desktop/source/deployment/manager/dp_manager.h | 2 | ||||
-rw-r--r-- | desktop/source/deployment/misc/dp_misc.cxx | 7 | ||||
-rw-r--r-- | desktop/source/pkgchk/unopkg/unopkg_app.cxx | 2 | ||||
-rw-r--r-- | offapi/com/sun/star/deployment/XExtensionManager.idl | 8 | ||||
-rw-r--r-- | offapi/com/sun/star/deployment/XPackageManager.idl | 8 |
13 files changed, 177 insertions, 63 deletions
diff --git a/desktop/inc/app.hxx b/desktop/inc/app.hxx index 06dc4c76d027..22866ef6b689 100644 --- a/desktop/inc/app.hxx +++ b/desktop/inc/app.hxx @@ -126,14 +126,12 @@ class Desktop : public Application static sal_Bool isCrashReporterEnabled(); // first-start (ever) related methods - static bool newInstallation(); - static sal_Bool CheckExtensionDependencies(); static void DoRestartActionsIfNecessary( sal_Bool bQuickStart ); static void SetRestartState(); - void SynchronizeExtensionRepositories(bool force); + void SynchronizeExtensionRepositories(); void SetSplashScreenText( const ::rtl::OUString& rText ); void SetSplashScreenProgress( sal_Int32 ); diff --git a/desktop/source/app/app.cxx b/desktop/source/app/app.cxx index c3152ee79805..84f60b8eef55 100644 --- a/desktop/source/app/app.cxx +++ b/desktop/source/app/app.cxx @@ -152,6 +152,145 @@ static sal_Bool _bCrashReporterEnabled = sal_True; static ::rtl::OUString getBrandSharePreregBundledPathURL(); #endif +namespace { + +void removeTree(OUString const & url) { + osl::Directory dir(url); + switch (dir.open()) { + case osl::FileBase::E_None: + break; + case osl::FileBase::E_NOENT: + return; //TODO: SAL_WARN if recursive + default: + throw css::uno::RuntimeException( + "cannot open directory " + url, + css::uno::Reference< css::uno::XInterface >()); + } + for (;;) { + osl::DirectoryItem i; + osl::FileBase::RC rc = dir.getNextItem(i, SAL_MAX_UINT32); + if (rc == osl::FileBase::E_NOENT) { + break; + } + if (rc != osl::FileBase::E_None) { + throw css::uno::RuntimeException( + "cannot iterate directory " + url, + css::uno::Reference< css::uno::XInterface >()); + } + osl::FileStatus stat( + osl_FileStatus_Mask_Type | osl_FileStatus_Mask_FileName | + osl_FileStatus_Mask_FileURL); + if (i.getFileStatus(stat) != osl::FileBase::E_None) { + throw css::uno::RuntimeException( + "cannot stat in directory " + url, + css::uno::Reference< css::uno::XInterface >()); + } + if (stat.getFileType() == osl::FileStatus::Directory) { //TODO: symlinks + removeTree(stat.getFileURL()); + } else { + if (osl::File::remove(stat.getFileURL()) != osl::FileBase::E_None) { + throw css::uno::RuntimeException( + "cannot remove " + stat.getFileURL(), + css::uno::Reference< css::uno::XInterface >()); + } + } + } +} + +// Remove any existing UserInstallation's user/extensions/bundled cache +// remaining from old installations. Apparently due to the old +// share/prereg/bundled mechanism (disabled since +// 5c47e5f63a79a9e72ec4a100786b1bbf65137ed4 "fdo#51252 Disable copying +// share/prereg/bundled to avoid startup crashes"), that cache could contain +// corrupted information (like a UNO component registered twice, which got +// changed from active to passive registration in one LO version, but the +// version of the corresponding bundled extension only incremented in a later LO +// version). At least in theory, this function could be removed again once no +// UserInstallation can be poisoned by that old share/prereg/bundled mechanism +// any more. (But then Desktop::SynchronizeExtensionRepositories might need to +// be revisited, see 2d2b19dea1ab401b1b4971ff5b12b87bb11fd666 "Force +// ExtensionManager resync when the implementation changes" which effectively +// got reverted again now. Now, a mismatch between a UserInstallation's +// user/extensions/bundled and an installation's share/extensions will always be +// detected here and lead to a removal of user/extensions/bundled, so that +// Desktop::SynchronizeExtensionRepositories will then definitely resync +// share/extensions.) +void refreshBundledExtensionsDir() { + OUString buildId( + "${$BRAND_BASE_DIR/program/" SAL_CONFIGFILE("version") ":buildid}"); + rtl::Bootstrap::expandMacros(buildId); //TODO: detect failure + OUString dir("$BUNDLED_EXTENSIONS_USER"); + rtl::Bootstrap::expandMacros(dir); //TODO: detect failure + OUString url(dir + "/buildid"); + osl::File f(url); + switch (f.open(osl_File_OpenFlag_Read)) { + case osl::FileBase::E_None: + { + rtl::ByteSequence s1; + osl::FileBase::RC rc = f.readLine(s1); + if (f.close() != osl::FileBase::E_None) { + SAL_WARN("desktop", "cannot close " + url + " after reading"); + } + if (rc != osl::FileBase::E_None) { + throw css::uno::RuntimeException( + "cannot read from " + url, + css::uno::Reference< css::uno::XInterface >()); + } + OUString s2( + reinterpret_cast< char const * >(s1.getConstArray()), + s1.getLength(), RTL_TEXTENCODING_ISO_8859_1); + // using ISO 8859-1 avoids any and all conversion errors; the + // content should only be a subset of ASCII, anyway + if (s2 == buildId) { + return; + } + break; + } + case osl::FileBase::E_NOENT: + break; + default: + throw css::uno::RuntimeException( + "cannot open " + url + " for reading", + css::uno::Reference< css::uno::XInterface >()); + } + removeTree(dir); + switch (osl::Directory::createPath(dir)) { + case osl::FileBase::E_None: + case osl::FileBase::E_EXIST: + break; + default: + throw css::uno::RuntimeException( + "cannot create path " + dir, + css::uno::Reference< css::uno::XInterface >()); + } + if (f.open(osl_File_OpenFlag_Write | osl_File_OpenFlag_Create) != + osl::FileBase::E_None) + { + throw css::uno::RuntimeException( + "cannot open " + url + " for writing", + css::uno::Reference< css::uno::XInterface >()); + } + OString buf(OUStringToOString(buildId, RTL_TEXTENCODING_UTF8)); + // using UTF-8 avoids almost all conversion errors (and buildid + // containing single surrogate halves should never happen, anyway); the + // content should only be a subset of ASCII, anyway + sal_uInt64 n; + if (f.write(buf.getStr(), buf.getLength(), n) != osl::FileBase::E_None + || n != static_cast< sal_uInt32 >(buf.getLength())) + { + throw css::uno::RuntimeException( + "cannot write to " + url, + css::uno::Reference< css::uno::XInterface >()); + } + if (f.close() != osl::FileBase::E_None) { + throw css::uno::RuntimeException( + "cannot close " + url + " after writing", + css::uno::Reference< css::uno::XInterface >()); + } +} + +} + // ---------------------------------------------------------------------------- ResMgr* Desktop::GetDesktopResManager() @@ -633,6 +772,8 @@ void Desktop::Init() RTL_LOGFILE_CONTEXT( aLog, "desktop (cd100003) ::Desktop::Init" ); SetBootstrapStatus(BS_OK); + refreshBundledExtensionsDir(); + // Check for lastsynchronized file for bundled extensions in the user directory // and test if synchronzation is necessary! #ifndef ANDROID @@ -1607,14 +1748,10 @@ int Desktop::Main() // Check if bundled or shared extensions were added /removed // and process those extensions (has to be done before checking // the extension dependencies! - bool newInst = newInstallation(); - SynchronizeExtensionRepositories(newInst); - if ( newInst ) - { - bool bAbort = CheckExtensionDependencies(); - if ( bAbort ) - return EXIT_FAILURE; - } + SynchronizeExtensionRepositories(); + bool bAbort = CheckExtensionDependencies(); + if ( bAbort ) + return EXIT_FAILURE; { ::comphelper::ComponentContext aContext( xSMgr ); diff --git a/desktop/source/app/check_ext_deps.cxx b/desktop/source/app/check_ext_deps.cxx index 04b5cd75b1d6..dd01d9bbf4e5 100644 --- a/desktop/source/app/check_ext_deps.cxx +++ b/desktop/source/app/check_ext_deps.cxx @@ -347,9 +347,9 @@ static void impl_setNeedsCompatCheck() // to check if we need checking the dependencies of the extensions again, we compare // the build id of the office with the one of the last check //------------------------------------------------------------------------------ -bool Desktop::newInstallation() +static bool impl_needsCompatCheck() { - bool bNewInst = false; + bool bNeedsCheck = false; rtl::OUString aLastCheckBuildID; rtl::OUString aCurrentBuildID( UNISTRING( "${$BRAND_BASE_DIR/program/" SAL_CONFIGFILE("version") ":buildid}" ) ); rtl::Bootstrap::expandMacros( aCurrentBuildID ); @@ -371,18 +371,18 @@ bool Desktop::newInstallation() result >>= aLastCheckBuildID; if ( aLastCheckBuildID != aCurrentBuildID ) { - bNewInst = true; + bNeedsCheck = true; result <<= aCurrentBuildID; pset->setPropertyValue( OUString("LastCompatibilityCheckID"), result ); Reference< util::XChangesBatch >( pset, UNO_QUERY_THROW )->commitChanges(); } #ifdef DEBUG - bNewInst = true; + bNeedsCheck = true; #endif } catch (const com::sun::star::uno::Exception&) {} - return bNewInst; + return bNeedsCheck; } //------------------------------------------------------------------------------ @@ -390,6 +390,11 @@ bool Desktop::newInstallation() // When there are unresolved issues, we can't continue with startup sal_Bool Desktop::CheckExtensionDependencies() { + if (!impl_needsCompatCheck()) + { + return false; + } + uno::Reference< uno::XComponentContext > xContext = comphelper_getProcessComponentContext(); bool bDependenciesValid = impl_checkDependencies( xContext ); @@ -408,10 +413,10 @@ sal_Bool Desktop::CheckExtensionDependencies() return false; } -void Desktop::SynchronizeExtensionRepositories(bool force) +void Desktop::SynchronizeExtensionRepositories() { RTL_LOGFILE_CONTEXT(aLog,"desktop (jl) ::Desktop::SynchronizeExtensionRepositories"); - dp_misc::syncRepositories( force, new SilentCommandEnv( this ) ); + dp_misc::syncRepositories( new SilentCommandEnv( this ) ); } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/desktop/source/deployment/gui/dp_gui_extensioncmdqueue.cxx b/desktop/source/deployment/gui/dp_gui_extensioncmdqueue.cxx index 7795e3093cc3..29ded177175a 100644 --- a/desktop/source/deployment/gui/dp_gui_extensioncmdqueue.cxx +++ b/desktop/source/deployment/gui/dp_gui_extensioncmdqueue.cxx @@ -1124,7 +1124,7 @@ void ExtensionCmdQueue::acceptLicense( const uno::Reference< deployment::XPackag void ExtensionCmdQueue::syncRepositories( const uno::Reference< uno::XComponentContext > &xContext ) { - dp_misc::syncRepositories( false, new ProgressCmdEnv( xContext, NULL, OUSTR("Extension Manager") ) ); + dp_misc::syncRepositories( new ProgressCmdEnv( xContext, NULL, OUSTR("Extension Manager") ) ); } void ExtensionCmdQueue::stop() diff --git a/desktop/source/deployment/inc/dp_misc.h b/desktop/source/deployment/inc/dp_misc.h index df358d791a69..2410c1ba8670 100644 --- a/desktop/source/deployment/inc/dp_misc.h +++ b/desktop/source/deployment/inc/dp_misc.h @@ -154,8 +154,7 @@ void TRACE(::rtl::OUString const & sText); recently added or removed. */ DESKTOP_DEPLOYMENTMISC_DLLPUBLIC -void syncRepositories(bool force, - ::com::sun::star::uno::Reference< +void syncRepositories(::com::sun::star::uno::Reference< ::com::sun::star::ucb::XCommandEnvironment> const & xCmdEnv); } diff --git a/desktop/source/deployment/manager/dp_extensionmanager.cxx b/desktop/source/deployment/manager/dp_extensionmanager.cxx index 290df139a250..f2a6fce0a0ff 100644 --- a/desktop/source/deployment/manager/dp_extensionmanager.cxx +++ b/desktop/source/deployment/manager/dp_extensionmanager.cxx @@ -1223,7 +1223,7 @@ void ExtensionManager::reinstallDeployedExtensions( xPackageManager->reinstallDeployedPackages(xAbortChannel, xCmdEnv); //We must sync here, otherwise we will get exceptions when extensions //are removed. - dp_misc::syncRepositories(false, xCmdEnv); + dp_misc::syncRepositories(xCmdEnv); const uno::Sequence< Reference<deploy::XPackage> > extensions( xPackageManager->getDeployedPackages(xAbortChannel, xCmdEnv)); @@ -1278,7 +1278,7 @@ void ExtensionManager::synchronizeBundledPrereg( Reference<deploy::XPackageManager> xMgr = xPackageManagerFactory->getPackageManager(OUSTR("bundled_prereg")); - xMgr->synchronize(false, xAbortChannel, xCmdEnv); + xMgr->synchronize(xAbortChannel, xCmdEnv); progressBundled.update(OUSTR("\n\n")); uno::Sequence<Reference<deploy::XPackage> > extensions = xMgr->getDeployedPackages( @@ -1317,7 +1317,6 @@ void ExtensionManager::synchronizeBundledPrereg( } sal_Bool ExtensionManager::synchronize( - sal_Bool forceBundled, Reference<task::XAbortChannel> const & xAbortChannel, Reference<ucb::XCommandEnvironment> const & xCmdEnv ) throw (deploy::DeploymentException, @@ -1334,13 +1333,13 @@ sal_Bool ExtensionManager::synchronize( String sSynchronizingShared(StrSyncRepository::get()); sSynchronizingShared.SearchAndReplaceAllAscii( "%NAME", OUSTR("shared")); dp_misc::ProgressLevel progressShared(xCmdEnv, sSynchronizingShared); - bModified = getSharedRepository()->synchronize(false, xAbortChannel, xCmdEnv); + bModified = getSharedRepository()->synchronize(xAbortChannel, xCmdEnv); progressShared.update(OUSTR("\n\n")); String sSynchronizingBundled(StrSyncRepository::get()); sSynchronizingBundled.SearchAndReplaceAllAscii( "%NAME", OUSTR("bundled")); dp_misc::ProgressLevel progressBundled(xCmdEnv, sSynchronizingBundled); - bModified |= getBundledRepository()->synchronize(forceBundled, xAbortChannel, xCmdEnv); + bModified |= getBundledRepository()->synchronize(xAbortChannel, xCmdEnv); progressBundled.update(OUSTR("\n\n")); //Always determine the active extension. This is necessary for the diff --git a/desktop/source/deployment/manager/dp_extensionmanager.hxx b/desktop/source/deployment/manager/dp_extensionmanager.hxx index 05fcde825fbf..800d91f437b6 100644 --- a/desktop/source/deployment/manager/dp_extensionmanager.hxx +++ b/desktop/source/deployment/manager/dp_extensionmanager.hxx @@ -193,7 +193,6 @@ public: css::uno::RuntimeException); virtual sal_Bool SAL_CALL synchronize( - sal_Bool forceBundled, css::uno::Reference<css::task::XAbortChannel> const & xAbortChannel, css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv ) throw (css::deployment::DeploymentException, diff --git a/desktop/source/deployment/manager/dp_manager.cxx b/desktop/source/deployment/manager/dp_manager.cxx index d7c8a2a3a154..a088f516c8a7 100644 --- a/desktop/source/deployment/manager/dp_manager.cxx +++ b/desktop/source/deployment/manager/dp_manager.cxx @@ -1248,7 +1248,6 @@ void PackageManagerImpl::reinstallDeployedPackages( return m_readOnly; } bool PackageManagerImpl::synchronizeRemovedExtensions( - bool force, Reference<task::XAbortChannel> const & xAbortChannel, Reference<css::ucb::XCommandEnvironment> const & xCmdEnv) { @@ -1272,19 +1271,15 @@ bool PackageManagerImpl::synchronizeRemovedExtensions( if (bShared) url = makeURLAppendSysPathSegment( url + OUSTR("_"), i->second.fileName); - bool bRemoved = force; - + bool bRemoved = false; //Check if the URL to the extension is still the same - if (!bRemoved) - { - ::ucbhelper::Content contentExtension; + ::ucbhelper::Content contentExtension; - if (!create_ucb_content( - &contentExtension, url, - Reference<XCommandEnvironment>(), false)) - { - bRemoved = true; - } + if (!create_ucb_content( + &contentExtension, url, + Reference<XCommandEnvironment>(), false)) + { + bRemoved = true; } //The folder is in the extension database, but it can still be deleted. @@ -1469,7 +1464,6 @@ bool PackageManagerImpl::synchronizeAddedExtensions( } sal_Bool PackageManagerImpl::synchronize( - sal_Bool force, Reference<task::XAbortChannel> const & xAbortChannel, Reference<css::ucb::XCommandEnvironment> const & xCmdEnv) throw (css::deployment::DeploymentException, @@ -1482,7 +1476,7 @@ sal_Bool PackageManagerImpl::synchronize( if (m_context.equals(OUSTR("user"))) return bModified; bModified |= - synchronizeRemovedExtensions(force, xAbortChannel, xCmdEnv); + synchronizeRemovedExtensions(xAbortChannel, xCmdEnv); bModified |= synchronizeAddedExtensions(xAbortChannel, xCmdEnv); return bModified; diff --git a/desktop/source/deployment/manager/dp_manager.h b/desktop/source/deployment/manager/dp_manager.h index cb3cbe82357b..b88b51111062 100644 --- a/desktop/source/deployment/manager/dp_manager.h +++ b/desktop/source/deployment/manager/dp_manager.h @@ -82,7 +82,6 @@ class PackageManagerImpl : private ::dp_misc::MutexHolder, public t_pm_helper css::uno::Reference<css::deployment::XPackage> const & package); bool synchronizeRemovedExtensions( - bool force, css::uno::Reference<css::task::XAbortChannel> const & xAbortChannel, css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv); @@ -240,7 +239,6 @@ public: throw (::com::sun::star::uno::RuntimeException); virtual ::sal_Bool SAL_CALL synchronize( - sal_Bool force, css::uno::Reference<css::task::XAbortChannel> const & xAbortChannel, css::uno::Reference<css::ucb::XCommandEnvironment> const & xCmdEnv ) throw (css::deployment::DeploymentException, diff --git a/desktop/source/deployment/misc/dp_misc.cxx b/desktop/source/deployment/misc/dp_misc.cxx index 6f47e3df9c2c..ba9c98384c1d 100644 --- a/desktop/source/deployment/misc/dp_misc.cxx +++ b/desktop/source/deployment/misc/dp_misc.cxx @@ -546,7 +546,7 @@ void TRACE(::rtl::OUString const & sText) } void syncRepositories( - bool force, Reference<ucb::XCommandEnvironment> const & xCmdEnv) + Reference<ucb::XCommandEnvironment> const & xCmdEnv) { OUString sDisable; ::rtl::Bootstrap::get( OUSTR( "DISABLE_EXTENSION_SYNCHRONIZATION" ), sDisable, OUString() ); @@ -557,8 +557,7 @@ void syncRepositories( //synchronize shared before bundled otherewise there are //more revoke and registration calls. sal_Bool bModified = false; - if (force - || needToSyncRepostitory(OUString(RTL_CONSTASCII_USTRINGPARAM("shared"))) + if (needToSyncRepostitory(OUString(RTL_CONSTASCII_USTRINGPARAM("shared"))) || needToSyncRepostitory(OUString(RTL_CONSTASCII_USTRINGPARAM("bundled")))) { xExtensionManager = @@ -568,7 +567,7 @@ void syncRepositories( if (xExtensionManager.is()) { bModified = xExtensionManager->synchronize( - force, Reference<task::XAbortChannel>(), xCmdEnv); + Reference<task::XAbortChannel>(), xCmdEnv); } } diff --git a/desktop/source/pkgchk/unopkg/unopkg_app.cxx b/desktop/source/pkgchk/unopkg/unopkg_app.cxx index 205e6ef82a31..2bd4d1b99214 100644 --- a/desktop/source/pkgchk/unopkg/unopkg_app.cxx +++ b/desktop/source/pkgchk/unopkg/unopkg_app.cxx @@ -432,7 +432,7 @@ extern "C" DESKTOP_DLLPUBLIC int unopkg_main() if (!subcmd_gui && ! subCommand.equals(OUSTR("reinstall")) && ! subCommand.equals(OUSTR("sync")) && ! dp_misc::office_is_running()) - dp_misc::syncRepositories(false, xCmdEnv); + dp_misc::syncRepositories(xCmdEnv); if ( subcmd_add || subCommand == "remove" ) { diff --git a/offapi/com/sun/star/deployment/XExtensionManager.idl b/offapi/com/sun/star/deployment/XExtensionManager.idl index 3809d905fa5a..7744ea6d839e 100644 --- a/offapi/com/sun/star/deployment/XExtensionManager.idl +++ b/offapi/com/sun/star/deployment/XExtensionManager.idl @@ -285,19 +285,11 @@ interface XExtensionManager The active extensions are determined. That is, shared or bundled extensions are not necessaryly registered (<member>XPackage::registerPackage</member>). - @param forceBundled - whether to reinstall all bundled extensions even if their versions - have not changed (which might be necessary when an upgraded - installation outdates references to any share/prereg/bundled/ - data; this parameter can go again once no exisiting - UserInstallation's user/extensions/bundled/ data can contain any - $BUNDLED_EXTENSIONS_PREREG references any longer) @return If true - then at least one extension was removed or added. Otherwise nothing was changed. */ boolean synchronize( - [in] boolean forceBundled, [in] com::sun::star::task::XAbortChannel xAbortChannel, [in] com::sun::star::ucb::XCommandEnvironment xCmdEnv ) raises (DeploymentException, diff --git a/offapi/com/sun/star/deployment/XPackageManager.idl b/offapi/com/sun/star/deployment/XPackageManager.idl index 842efdf3b5e4..65cb24a6ac0f 100644 --- a/offapi/com/sun/star/deployment/XPackageManager.idl +++ b/offapi/com/sun/star/deployment/XPackageManager.idl @@ -259,10 +259,6 @@ interface XPackageManager Added extensions will be added to the database and removed extensions will be removed from the database. - @param force - whether to reinstall all extensions even if their versions have not - changed (see forceBundled parameter of - XExtensionManager.synchronize) @param xAddedExtension new extensions which may need to be registered. @@ -272,9 +268,7 @@ interface XPackageManager If true - then at least one extension was removed or added. Otherwise nothing was changed. */ - boolean synchronize( - [in] boolean force, - [in] com::sun::star::task::XAbortChannel xAbortChannel, + boolean synchronize([in] com::sun::star::task::XAbortChannel xAbortChannel, [in] com::sun::star::ucb::XCommandEnvironment xCmdEnv ) raises (DeploymentException, com::sun::star::ucb::CommandFailedException, |