common/Session.cpp | 7 + common/Session.hpp | 2 kit/ChildSession.cpp | 184 +++++++++++++++------------------------------- kit/ChildSession.hpp | 7 - kit/Kit.cpp | 30 +------ test/Makefile.am | 9 +- test/UnitWOPITemplate.cpp | 172 +++++++++++++++++++++++++++++++++++++++++++ test/WhiteBoxTests.cpp | 8 -- test/data/test.ott |binary wsd/ClientSession.cpp | 16 +++- wsd/DocumentBroker.cpp | 10 ++ wsd/LOOLWSD.cpp | 3 wsd/Storage.cpp | 24 ++++-- wsd/Storage.hpp | 14 ++- 14 files changed, 311 insertions(+), 175 deletions(-)
New commits: commit 760864870fa8992fda58be03f3f55232b247506f Author: Henry Castro <hcas...@collabora.com> AuthorDate: Tue May 21 23:33:26 2019 -0400 Commit: Jan Holesovsky <ke...@collabora.com> CommitDate: Wed Jul 24 12:10:15 2019 +0200 wsd: introduce "TemplateSource" WOPI property Change-Id: I9df1d5d0d4be7fe10ee15c40c36195c86ccf857e Reviewed-on: https://gerrit.libreoffice.org/76190 Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com> Reviewed-by: Jan Holesovsky <ke...@collabora.com> diff --git a/common/Session.cpp b/common/Session.cpp index 1c37e5ba2..5c8d11568 100644 --- a/common/Session.cpp +++ b/common/Session.cpp @@ -75,7 +75,7 @@ bool Session::sendBinaryFrame(const char *buffer, int length) return sendMessage(buffer, length, WSOpCode::Binary) >= length; } -void Session::parseDocOptions(const std::vector<std::string>& tokens, int& part, std::string& timestamp) +void Session::parseDocOptions(const std::vector<std::string>& tokens, int& part, std::string& timestamp, std::string& doctemplate) { // First token is the "load" command itself. size_t offset = 1; @@ -161,6 +161,11 @@ void Session::parseDocOptions(const std::vector<std::string>& tokens, int& part, timestamp = value; ++offset; } + else if (name == "template") + { + doctemplate = value; + ++offset; + } } Util::mapAnonymized(_userId, _userIdAnonym); diff --git a/common/Session.hpp b/common/Session.hpp index f09af7574..ddee50d55 100644 --- a/common/Session.hpp +++ b/common/Session.hpp @@ -124,7 +124,7 @@ protected: /// Parses the options of the "load" command, /// shared between MasterProcessSession::loadDocument() and ChildProcessSession::loadDocument(). - void parseDocOptions(const std::vector<std::string>& tokens, int& part, std::string& timestamp); + void parseDocOptions(const std::vector<std::string>& tokens, int& part, std::string& timestamp, std::string& doctemplate); void updateLastActivityTime() { diff --git a/kit/ChildSession.cpp b/kit/ChildSession.cpp index 60cf4c087..a229ae5f0 100644 --- a/kit/ChildSession.cpp +++ b/kit/ChildSession.cpp @@ -534,8 +534,8 @@ bool ChildSession::loadDocument(const char * /*buffer*/, int /*length*/, const s return false; } - std::string timestamp; - parseDocOptions(tokens, part, timestamp); + std::string timestamp, doctemplate; + parseDocOptions(tokens, part, timestamp, doctemplate); std::string renderOpts; if (!getDocOptions().empty()) @@ -556,7 +556,7 @@ bool ChildSession::loadDocument(const char * /*buffer*/, int /*length*/, const s const bool loaded = _docManager.onLoad(getId(), getJailedFilePath(), getJailedFilePathAnonym(), getUserName(), getUserNameAnonym(), getDocPassword(), renderOpts, getHaveDocPassword(), - getLang(), getWatermarkText()); + getLang(), getWatermarkText(), doctemplate); if (!loaded || _viewId < 0) { LOG_ERR("Failed to get LoKitDocument instance for [" << getJailedFilePathAnonym() << "]."); @@ -566,6 +566,17 @@ bool ChildSession::loadDocument(const char * /*buffer*/, int /*length*/, const s LOG_INF("Created new view with viewid: [" << _viewId << "] for username: [" << getUserNameAnonym() << "] in session: [" << getId() << "]."); + if (!doctemplate.empty()) + { + std::string url = getJailedFilePath(); + bool success = getLOKitDocument()->saveAs(url.c_str(), nullptr, nullptr); + if (!success) + { + LOG_ERR("Failed to save template [" << getJailedFilePath() << "]."); + return false; + } + } + getLOKitDocument()->setView(_viewId); _docType = LOKitHelper::getDocumentTypeAsString(getLOKitDocument()->get()); diff --git a/kit/ChildSession.hpp b/kit/ChildSession.hpp index 215d1ad4b..bb6a3d720 100644 --- a/kit/ChildSession.hpp +++ b/kit/ChildSession.hpp @@ -46,7 +46,8 @@ public: const std::string& renderOpts, const bool haveDocPassword, const std::string& lang, - const std::string& watermarkText) = 0; + const std::string& watermarkText, + const std::string& docTemplate) = 0; /// Unload a client session, which unloads the document /// if it is the last and only. diff --git a/kit/Kit.cpp b/kit/Kit.cpp index 2f0d63f21..bb79c2766 100644 --- a/kit/Kit.cpp +++ b/kit/Kit.cpp @@ -1458,7 +1458,8 @@ private: const std::string& renderOpts, const bool haveDocPassword, const std::string& lang, - const std::string& watermarkText) override + const std::string& watermarkText, + const std::string& docTemplate) override { std::unique_lock<std::mutex> lock(_mutex); @@ -1487,7 +1488,7 @@ private: try { - if (!load(session, uri, uriAnonym, userName, userNameAnonym, docPassword, renderOpts, haveDocPassword, lang, watermarkText)) + if (!load(session, uri, uriAnonym, userName, userNameAnonym, docPassword, renderOpts, haveDocPassword, lang, watermarkText, docTemplate)) { return false; } @@ -1729,7 +1730,8 @@ private: const std::string& renderOpts, const bool haveDocPassword, const std::string& lang, - const std::string& watermarkText) + const std::string& watermarkText, + const std::string& docTemplate) { const std::string sessionId = session->getId(); @@ -1760,7 +1762,7 @@ private: LOG_DBG("Calling lokit::documentLoad(" << uriAnonym << ", \"" << options << "\")."); Timestamp timestamp; - _loKitDocument.reset(_loKit->documentLoad(uri.c_str(), options.c_str())); + _loKitDocument.reset(_loKit->documentLoad(docTemplate.empty() ? uri.c_str() : docTemplate.c_str(), options.c_str())); LOG_DBG("Returned lokit::documentLoad(" << uriAnonym << ") in " << (timestamp.elapsed() / 1000.) << "ms."); #ifdef IOS // The iOS app (and the Android one) has max one document open at a time, so we can keep diff --git a/test/Makefile.am b/test/Makefile.am index f1f43aee9..02e15614a 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -9,7 +9,7 @@ check_PROGRAMS = test fakesockettest noinst_PROGRAMS = test fakesockettest unittest -AM_CXXFLAGS = $(CPPUNIT_CFLAGS) -DTDOC=\"$(top_srcdir)/test/data\" \ +AM_CXXFLAGS = $(CPPUNIT_CFLAGS) -DTDOC=\"$(abs_top_srcdir)/test/data\" \ -I${top_srcdir}/common -I${top_srcdir}/net -I${top_srcdir}/wsd -I${top_srcdir}/kit noinst_LTLIBRARIES = \ @@ -21,8 +21,7 @@ noinst_LTLIBRARIES = \ unit-wopi.la unit-wopi-saveas.la \ unit-wopi-ownertermination.la unit-wopi-versionrestore.la \ unit-wopi-documentconflict.la unit_wopi_renamefile.la \ - unit-wopi-loadencoded.la - + unit-wopi-loadencoded.la unit-wopi-temp.la MAGIC_TO_FORCE_SHLIB_CREATION = -rpath /dummy AM_LDFLAGS = -pthread -module $(MAGIC_TO_FORCE_SHLIB_CREATION) $(ZLIB_LIBS) @@ -116,6 +115,8 @@ unit_wopi_renamefile_la_SOURCES = UnitWOPIRenameFile.cpp unit_wopi_renamefile_la_LIBADD = $(CPPUNIT_LIBS) unit_wopi_loadencoded_la_SOURCES = UnitWOPILoadEncoded.cpp unit_wopi_loadencoded_la_LIBADD = $(CPPUNIT_LIBS) +unit_wopi_temp_la_SOURCES = UnitWOPITemplate.cpp +unit_wopi_temp_la_LIBADD = $(CPPUNIT_LIBS) if HAVE_LO_PATH SYSTEM_STAMP = @SYSTEMPLATE_PATH@/system_stamp @@ -136,7 +137,7 @@ TESTS = unit-typing.la unit-convert.la unit-prefork.la unit-tilecache.la \ unit-wopi-ownertermination.la unit-wopi-versionrestore.la \ unit-wopi-documentconflict.la unit_wopi_renamefile.la \ unit-http.la \ - unit-wopi-loadencoded.la + unit-wopi-loadencoded.la unit-wopi-temp.la # TESTS = unit-client.la # TESTS += unit-admin.la # TESTS += unit-storage.la diff --git a/test/UnitWOPITemplate.cpp b/test/UnitWOPITemplate.cpp new file mode 100644 index 000000000..1ab588799 --- /dev/null +++ b/test/UnitWOPITemplate.cpp @@ -0,0 +1,172 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include <config.h> + +#include <WopiTestServer.hpp> +#include <Log.hpp> +#include <Unit.hpp> +#include <UnitHTTP.hpp> +#include <helpers.hpp> +#include <Poco/Net/HTTPRequest.h> +#include <Poco/Util/LayeredConfiguration.h> + +class UnitWOPITemplate : public WopiTestServer +{ + enum class Phase + { + LoadTemplate, + SaveDoc, + CloseDoc, + Polling + } _phase; + +public: + UnitWOPITemplate() : + _phase(Phase::LoadTemplate) + { + } + + virtual bool handleHttpRequest(const Poco::Net::HTTPRequest& request, Poco::MemoryInputStream& /*message*/, std::shared_ptr<StreamSocket>& socket) override + { + Poco::URI uriReq(request.getURI()); + LOG_INF("Fake wopi host request: " << uriReq.toString() << " method " << request.getMethod()); + + // CheckFileInfo + if (request.getMethod() == "GET" && uriReq.getPath() == "/wopi/files/10") + { + LOG_INF("Fake wopi host request, handling CheckFileInfo: " << uriReq.getPath()); + + Poco::LocalDateTime now; + Poco::JSON::Object::Ptr fileInfo = new Poco::JSON::Object(); + fileInfo->set("BaseFileName", "test.odt"); + fileInfo->set("TemplateSource", std::string("http://127.0.0.1:") + std::to_string(helpers::getClientPort()) + "/test.ott"); // must be http, otherwise Neon in the core complains + fileInfo->set("Size", _fileContent.size()); + fileInfo->set("Version", "1.0"); + fileInfo->set("OwnerId", "test"); + fileInfo->set("UserId", "test"); + fileInfo->set("UserFriendlyName", "test"); + fileInfo->set("UserCanWrite", "true"); + fileInfo->set("PostMessageOrigin", "localhost"); + fileInfo->set("LastModifiedTime", Poco::DateTimeFormatter::format(Poco::DateTime(_fileLastModifiedTime), Poco::DateTimeFormat::ISO8601_FRAC_FORMAT)); + fileInfo->set("EnableOwnerTermination", "true"); + + std::ostringstream jsonStream; + fileInfo->stringify(jsonStream); + std::string responseString = jsonStream.str(); + + const std::string mimeType = "application/json; charset=utf-8"; + + std::ostringstream oss; + oss << "HTTP/1.1 200 OK\r\n" + << "Last-Modified: " << Poco::DateTimeFormatter::format(_fileLastModifiedTime, Poco::DateTimeFormat::HTTP_FORMAT) << "\r\n" + << "User-Agent: " << WOPI_AGENT_STRING << "\r\n" + << "Content-Length: " << responseString.size() << "\r\n" + << "Content-Type: " << mimeType << "\r\n" + << "\r\n" + << responseString; + + socket->send(oss.str()); + socket->shutdown(); + + return true; + } + else if ((request.getMethod() == "OPTIONS" || request.getMethod() == "HEAD" || request.getMethod() == "PROPFIND") && uriReq.getPath() == "/test.ott") + { + std::ostringstream oss; + oss << "HTTP/1.1 200 OK\r\n" + << "Allow: GET\r\n" + << "User-Agent: " << WOPI_AGENT_STRING << "\r\n" + << "\r\n"; + + socket->send(oss.str()); + socket->shutdown(); + + return true; + } + // Get the template + else if (request.getMethod() == "GET" && uriReq.getPath() == "/test.ott") + { + LOG_INF("Fake wopi host request, handling template GetFile: " << uriReq.getPath()); + + Poco::Net::HTTPResponse response; + HttpHelper::sendFile(socket, TDOC "/test.ott", "", response); + socket->shutdown(); + + return true; + } + // Save template + else if (request.getMethod() == "POST" && uriReq.getPath() == "/wopi/files/10/contents") + { + LOG_INF("Fake wopi host request, handling PutFile: " << uriReq.getPath()); + + std::streamsize size = request.getContentLength(); + CPPUNIT_ASSERT( size > 0 ); + + std::ostringstream oss; + oss << "HTTP/1.1 200 OK\r\n" + << "User-Agent: " << WOPI_AGENT_STRING << "\r\n" + << "\r\n" + << "{\"LastModifiedTime\": \"" << Poco::DateTimeFormatter::format(_fileLastModifiedTime, Poco::DateTimeFormat::ISO8601_FRAC_FORMAT) << "\" }"; + + socket->send(oss.str()); + socket->shutdown(); + + CPPUNIT_ASSERT_EQUAL(static_cast<int>(Phase::SaveDoc), static_cast<int>(_phase)); + _phase = Phase::CloseDoc; + + return true; + } + + + return false; + } + + + void invokeTest() override + { + constexpr char testName[] = "UnitWOPITemplate"; + + switch (_phase) + { + case Phase::LoadTemplate: + { + initWebsocket("/wopi/files/10?access_token=anything"); + + helpers::sendTextFrame(*_ws->getLOOLWebSocket(), "load url=" + _wopiSrc, testName); + SocketPoll::wakeupWorld(); + + _phase = Phase::SaveDoc; + break; + } + case Phase::CloseDoc: + { + helpers::sendTextFrame(*_ws->getLOOLWebSocket(), "closedocument", testName); + _phase = Phase::Polling; + break; + } + case Phase::Polling: + { + exitTest(TestResult::Ok); + break; + } + case Phase::SaveDoc: + { + break; + } + } + } +}; + +UnitBase *unit_create_wsd(void) +{ + return new UnitWOPITemplate(); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/test/WhiteBoxTests.cpp b/test/WhiteBoxTests.cpp index 38bb627d0..8c5bdc70c 100644 --- a/test/WhiteBoxTests.cpp +++ b/test/WhiteBoxTests.cpp @@ -500,7 +500,8 @@ public: const std::string& /*renderOpts*/, const bool /*haveDocPassword*/, const std::string& /*lang*/, - const std::string& /*watermarkText*/) override + const std::string& /*watermarkText*/, + const std::string& /*docTemplate*/) override { return false; } diff --git a/test/data/test.ott b/test/data/test.ott new file mode 100644 index 000000000..d7f63419c Binary files /dev/null and b/test/data/test.ott differ diff --git a/wsd/ClientSession.cpp b/wsd/ClientSession.cpp index 42e3fa2c4..6838e24ff 100644 --- a/wsd/ClientSession.cpp +++ b/wsd/ClientSession.cpp @@ -429,9 +429,9 @@ bool ClientSession::loadDocument(const char* /*buffer*/, int /*length*/, LOG_INF("Requesting document load from child."); try { - std::string timestamp; + std::string timestamp, doctemplate; int loadPart = -1; - parseDocOptions(tokens, loadPart, timestamp); + parseDocOptions(tokens, loadPart, timestamp, doctemplate); std::ostringstream oss; oss << "load"; @@ -490,6 +490,11 @@ bool ClientSession::loadDocument(const char* /*buffer*/, int /*length*/, oss << " options=" << getDocOptions(); } + if (_wopiFileInfo && !_wopiFileInfo->getTemplateSource().empty()) + { + oss << " template=" << _wopiFileInfo->getTemplateSource(); + } + return forwardToChild(oss.str(), docBroker); } catch (const Poco::SyntaxException&) @@ -956,6 +961,13 @@ bool ClientSession::handleKitToClientMessage(const char* buffer, const int lengt { setViewLoaded(); docBroker->setLoaded(); + // Wopi post load actions + if (_wopiFileInfo && !_wopiFileInfo->getTemplateSource().empty()) + { + std::string result; + LOG_DBG("Saving template [" << _wopiFileInfo->getTemplateSource() << "] to storage"); + docBroker->saveToStorage(getId(), true, result); + } for(auto &token : tokens) { diff --git a/wsd/DocumentBroker.cpp b/wsd/DocumentBroker.cpp index 8429aa96f..8f2a6016d 100644 --- a/wsd/DocumentBroker.cpp +++ b/wsd/DocumentBroker.cpp @@ -518,6 +518,7 @@ bool DocumentBroker::load(const std::shared_ptr<ClientSession>& session, const s std::string userId, username; std::string userExtraInfo; std::string watermarkText; + std::string templateSource; #if !MOBILEAPP std::chrono::duration<double> getInfoCallDuration(0); @@ -529,6 +530,7 @@ bool DocumentBroker::load(const std::shared_ptr<ClientSession>& session, const s username = wopifileinfo->getUsername(); userExtraInfo = wopifileinfo->getUserExtraInfo(); watermarkText = wopifileinfo->getWatermarkText(); + templateSource = wopifileinfo->getTemplateSource(); if (!wopifileinfo->getUserCanWrite() || LOOLWSD::IsViewFileExtension(wopiStorage->getFileExtension())) @@ -563,6 +565,9 @@ bool DocumentBroker::load(const std::shared_ptr<ClientSession>& session, const s if (!wopifileinfo->getTemplateSaveAs().empty()) wopiInfo->set("TemplateSaveAs", wopifileinfo->getTemplateSaveAs()); + if (!templateSource.empty()) + wopiInfo->set("TemplateSource", templateSource); + wopiInfo->set("HidePrintOption", wopifileinfo->getHidePrintOption()); wopiInfo->set("HideSaveOption", wopifileinfo->getHideSaveOption()); wopiInfo->set("HideExportOption", wopifileinfo->getHideExportOption()); @@ -675,7 +680,7 @@ bool DocumentBroker::load(const std::shared_ptr<ClientSession>& session, const s // Let's load the document now, if not loaded. if (!_storage->isLoaded()) { - std::string localPath = _storage->loadStorageFileToLocal(session->getAuthorization()); + std::string localPath = _storage->loadStorageFileToLocal(session->getAuthorization(), templateSource); #if !MOBILEAPP // Check if we have a prefilter "plugin" for this document format @@ -748,7 +753,8 @@ bool DocumentBroker::load(const std::shared_ptr<ClientSession>& session, const s _filename = fileInfo.getFilename(); // Use the local temp file's timestamp. - _lastFileModifiedTime = Poco::File(_storage->getRootFilePath()).getLastModified(); + _lastFileModifiedTime = templateSource.empty() ? Poco::File(_storage->getRootFilePath()).getLastModified() : + Poco::Timestamp::fromEpochTime(0); bool dontUseCache = false; #if MOBILEAPP diff --git a/wsd/LOOLWSD.cpp b/wsd/LOOLWSD.cpp index 10de1580c..fc5de67a3 100644 --- a/wsd/LOOLWSD.cpp +++ b/wsd/LOOLWSD.cpp @@ -2823,6 +2823,9 @@ private: // Supports the TemplateSaveAs in CheckFileInfo? capabilities->set("hasTemplateSaveAs", true); + // Supports the TemplateSource in CheckFileInfo? + capabilities->set("hasTemplateSource", true); + // Hint to encourage use on mobile devices capabilities->set("hasMobileSupport", true); diff --git a/wsd/Storage.cpp b/wsd/Storage.cpp index 4b914ca2a..c13498c09 100644 --- a/wsd/Storage.cpp +++ b/wsd/Storage.cpp @@ -272,7 +272,7 @@ std::unique_ptr<LocalStorage::LocalFileInfo> LocalStorage::getLocalFileInfo() return std::unique_ptr<LocalStorage::LocalFileInfo>(new LocalFileInfo({"localhost" + std::to_string(LastLocalStorageId), "LocalHost#" + std::to_string(LastLocalStorageId++)})); } -std::string LocalStorage::loadStorageFileToLocal(const Authorization& /*auth*/) +std::string LocalStorage::loadStorageFileToLocal(const Authorization& /*auth*/, const std::string& /*templateUri*/) { #if !MOBILEAPP // /chroot/jailId/user/doc/childId/file.ext @@ -485,6 +485,7 @@ std::unique_ptr<WopiStorage::WOPIFileInfo> WopiStorage::getWOPIFileInfo(const Au std::string userExtraInfo; std::string watermarkText; std::string templateSaveAs; + std::string templateSource; bool canWrite = false; bool enableOwnerTermination = false; std::string postMessageOrigin; @@ -520,6 +521,7 @@ std::unique_ptr<WopiStorage::WOPIFileInfo> WopiStorage::getWOPIFileInfo(const Au JsonUtil::findJSONValue(object, "UserId", userId); JsonUtil::findJSONValue(object, "UserFriendlyName", userName); JsonUtil::findJSONValue(object, "TemplateSaveAs", templateSaveAs); + JsonUtil::findJSONValue(object, "TemplateSource", templateSource); // Anonymize key values. if (LOOLWSD::AnonymizeFilenames || LOOLWSD::AnonymizeUsernames) @@ -558,6 +560,7 @@ std::unique_ptr<WopiStorage::WOPIFileInfo> WopiStorage::getWOPIFileInfo(const Au { object->remove("BaseFileName"); object->remove("TemplateSaveAs"); + object->remove("TemplateSource"); } if (LOOLWSD::AnonymizeUsernames) @@ -615,8 +618,8 @@ std::unique_ptr<WopiStorage::WOPIFileInfo> WopiStorage::getWOPIFileInfo(const Au setFileInfo(FileInfo({filename, ownerId, modifiedTime, size})); return std::unique_ptr<WopiStorage::WOPIFileInfo>(new WOPIFileInfo( - {userId, obfuscatedUserId, userName, userExtraInfo, watermarkText, templateSaveAs, canWrite, - postMessageOrigin, hidePrintOption, hideSaveOption, hideExportOption, + {userId, obfuscatedUserId, userName, userExtraInfo, watermarkText, templateSaveAs, templateSource, + canWrite, postMessageOrigin, hidePrintOption, hideSaveOption, hideExportOption, enableOwnerTermination, disablePrint, disableExport, disableCopy, disableInactiveMessages, downloadAsPostMessage, userCanNotWriteRelative, enableInsertRemoteImage, enableShare, hideUserList, disableChangeTrackingShow, disableChangeTrackingRecord, @@ -624,7 +627,7 @@ std::unique_ptr<WopiStorage::WOPIFileInfo> WopiStorage::getWOPIFileInfo(const Au } /// uri format: http://server/<...>/wopi*/files/<id>/content -std::string WopiStorage::loadStorageFileToLocal(const Authorization& auth) +std::string WopiStorage::loadStorageFileToLocal(const Authorization& auth, const std::string& templateUri) { // WOPI URI to download files ends in '/contents'. // Add it here to get the payload instead of file info. @@ -636,6 +639,17 @@ std::string WopiStorage::loadStorageFileToLocal(const Authorization& auth) uriObjectAnonym.setPath(LOOLWSD::anonymizeUrl(uriObjectAnonym.getPath()) + "/contents"); const std::string uriAnonym = uriObjectAnonym.toString(); + if (!templateUri.empty()) + { + // template are created in kit process, so just obtain a reference + setRootFilePath(Poco::Path(getLocalRootPath(), getFileInfo().getFilename()).toString()); + setRootFilePathAnonym(LOOLWSD::anonymizeUrl(getRootFilePath())); + LOG_INF("Template reference " << getRootFilePathAnonym()); + + setLoaded(true); + return Poco::Path(getJailPath(), getFileInfo().getFilename()).toString(); + } + LOG_DBG("Wopi requesting: " << uriAnonym); const auto startTime = std::chrono::steady_clock::now(); @@ -902,7 +916,7 @@ StorageBase::SaveResult WopiStorage::saveLocalFileToStorage(const Authorization& return saveResult; } -std::string WebDAVStorage::loadStorageFileToLocal(const Authorization& /*auth*/) +std::string WebDAVStorage::loadStorageFileToLocal(const Authorization& /*auth*/, const std::string& /*templateUri*/) { // TODO: implement webdav GET. setLoaded(true); diff --git a/wsd/Storage.hpp b/wsd/Storage.hpp index 6bfac902a..491341e9a 100644 --- a/wsd/Storage.hpp +++ b/wsd/Storage.hpp @@ -189,7 +189,7 @@ public: /// Returns a local file path for the given URI. /// If necessary copies the file locally first. - virtual std::string loadStorageFileToLocal(const Authorization& auth) = 0; + virtual std::string loadStorageFileToLocal(const Authorization& auth, const std::string& templateUri) = 0; /// Writes the contents of the file back to the source. /// @param savedFile When the operation was saveAs, this is the path to the file that was saved. @@ -272,7 +272,7 @@ public: /// obtained using getFileInfo method std::unique_ptr<LocalFileInfo> getLocalFileInfo(); - std::string loadStorageFileToLocal(const Authorization& auth) override; + std::string loadStorageFileToLocal(const Authorization& auth, const std::string& templateUri) override; SaveResult saveLocalFileToStorage(const Authorization& auth, const std::string& saveAsPath, const std::string& saveAsFilename, const bool isRename) override; @@ -312,6 +312,7 @@ public: const std::string& userExtraInfo, const std::string& watermarkText, const std::string& templateSaveAs, + const std::string& templateSource, const bool userCanWrite, const std::string& postMessageOrigin, const bool hidePrintOption, @@ -338,6 +339,7 @@ public: _username(username), _watermarkText(watermarkText), _templateSaveAs(templateSaveAs), + _templateSource(templateSource), _userCanWrite(userCanWrite), _postMessageOrigin(postMessageOrigin), _hidePrintOption(hidePrintOption), @@ -373,6 +375,8 @@ public: const std::string& getTemplateSaveAs() const { return _templateSaveAs; } + const std::string& getTemplateSource() const { return _templateSource; } + bool getUserCanWrite() const { return _userCanWrite; } std::string& getPostMessageOrigin() { return _postMessageOrigin; } @@ -432,6 +436,8 @@ public: std::string _watermarkText; /// In case we want to use this file as a template, it should be first re-saved under this name (using PutRelativeFile). std::string _templateSaveAs; + /// In case we want to use this file as a template. + std::string _templateSource; /// If user accessing the file has write permission bool _userCanWrite; /// WOPI Post message property @@ -486,7 +492,7 @@ public: std::unique_ptr<WOPIFileInfo> getWOPIFileInfo(const Authorization& auth); /// uri format: http://server/<...>/wopi*/files/<id>/content - std::string loadStorageFileToLocal(const Authorization& auth) override; + std::string loadStorageFileToLocal(const Authorization& auth, const std::string& templateUri) override; SaveResult saveLocalFileToStorage(const Authorization& auth, const std::string& saveAsPath, const std::string& saveAsFilename, const bool isRename) override; @@ -516,7 +522,7 @@ public: // Implement me // WebDAVFileInfo getWebDAVFileInfo(const Poco::URI& uriPublic); - std::string loadStorageFileToLocal(const Authorization& auth) override; + std::string loadStorageFileToLocal(const Authorization& auth, const std::string& templateUri) override; SaveResult saveLocalFileToStorage(const Authorization& auth, const std::string& saveAsPath, const std::string& saveAsFilename, const bool isRename) override; commit f7a70ba9d3411953ca4147ac8cc484dd8745b5b7 Author: Tor Lillqvist <t...@collabora.com> AuthorDate: Thu Jul 18 12:00:58 2019 +0300 Commit: Jan Holesovsky <ke...@collabora.com> CommitDate: Wed Jul 24 12:09:24 2019 +0200 tdf#125681: Get rid of ChildSession::getDocumentMutex() and associated code Now with the "Unipoll" concept all this locking is unnecessary as the kit process is single-threaded, and actually it is harmful as the bug shows. Michael explains in chat: But in fact - we should be a single threaded kit process there now. We are protected by the solar-mutex (which is recursive) while our locking is not. This was the whole point of the Unipoll refactor: to remove the extra threads, complex queues, etc. etc. I just left the mutexes. Even a recursive mutex won't work there; since it needs to be drop-able and transferable to another (LOK internal thread) in Yield, so - we should remove them. Change-Id: I7d1e1dfb0e20f14134be5f81da057539b0f86ab9 Reviewed-on: https://gerrit.libreoffice.org/75849 Reviewed-by: Michael Meeks <michael.me...@collabora.com> Tested-by: Michael Meeks <michael.me...@collabora.com> diff --git a/kit/ChildSession.cpp b/kit/ChildSession.cpp index d8255442e..60cf4c087 100644 --- a/kit/ChildSession.cpp +++ b/kit/ChildSession.cpp @@ -122,7 +122,6 @@ bool ChildSession::_handleInput(const char *buffer, int length) // Client is getting active again. // Send invalidation and other sync-up messages. std::unique_lock<std::recursive_mutex> lock(Mutex); //TODO: Move to top of function? - std::unique_lock<std::mutex> lockLokDoc(_docManager.getDocumentMutex()); getLOKitDocument()->setView(_viewId); @@ -133,8 +132,6 @@ bool ChildSession::_handleInput(const char *buffer, int length) // Notify all views about updated view info _docManager.notifyViewInfo(); - lockLokDoc.unlock(); - if (getLOKitDocument()->getDocumentType() != LOK_DOCTYPE_TEXT) { sendTextFrame("curpart: part=" + std::to_string(curPart)); @@ -456,13 +453,9 @@ bool ChildSession::uploadSignedDocument(const char* buffer, int length, const st const Poco::Path filenameParam(filename); const std::string url = JAILED_DOCUMENT_ROOT + tmpDir + "/" + filenameParam.getFileName(); - { - std::unique_lock<std::mutex> lock(_docManager.getDocumentMutex()); - - getLOKitDocument()->saveAs(url.c_str(), - filetype.empty() ? nullptr : filetype.c_str(), - nullptr); - } + getLOKitDocument()->saveAs(url.c_str(), + filetype.empty() ? nullptr : filetype.c_str(), + nullptr); Authorization authorization(Authorization::Type::Token, token); Poco::URI uriObject(wopiUrl + "/" + filename + "/contents"); @@ -573,8 +566,6 @@ bool ChildSession::loadDocument(const char * /*buffer*/, int /*length*/, const s LOG_INF("Created new view with viewid: [" << _viewId << "] for username: [" << getUserNameAnonym() << "] in session: [" << getId() << "]."); - std::unique_lock<std::mutex> lockLokDoc(_docManager.getDocumentMutex()); - getLOKitDocument()->setView(_viewId); _docType = LOKitHelper::getDocumentTypeAsString(getLOKitDocument()->get()); @@ -638,13 +629,9 @@ bool ChildSession::sendFontRendering(const char* /*buffer*/, int /*length*/, con int width = 0, height = 0; unsigned char* ptrFont = nullptr; - { - std::unique_lock<std::mutex> lock(_docManager.getDocumentMutex()); - - getLOKitDocument()->setView(_viewId); + getLOKitDocument()->setView(_viewId); - ptrFont = getLOKitDocument()->renderFont(decodedFont.c_str(), decodedChar.c_str(), &width, &height); - } + ptrFont = getLOKitDocument()->renderFont(decodedFont.c_str(), decodedChar.c_str(), &width, &height); LOG_TRC("renderFont [" << font << "] rendered in " << (timestamp.elapsed()/1000.) << "ms"); @@ -671,13 +658,10 @@ bool ChildSession::sendFontRendering(const char* /*buffer*/, int /*length*/, con bool ChildSession::getStatus(const char* /*buffer*/, int /*length*/) { std::string status; - { - std::unique_lock<std::mutex> lock(_docManager.getDocumentMutex()); - getLOKitDocument()->setView(_viewId); + getLOKitDocument()->setView(_viewId); - status = LOKitHelper::documentStatus(getLOKitDocument()->get()); - } + status = LOKitHelper::documentStatus(getLOKitDocument()->get()); if (status.empty()) { @@ -731,8 +715,6 @@ bool ChildSession::getCommandValues(const char* /*buffer*/, int /*length*/, cons return false; } - std::unique_lock<std::mutex> lock(_docManager.getDocumentMutex()); - getLOKitDocument()->setView(_viewId); if (command == ".uno:DocumentRepair") @@ -775,8 +757,6 @@ bool ChildSession::clientZoom(const char* /*buffer*/, int /*length*/, const std: return false; } - std::unique_lock<std::mutex> lock(_docManager.getDocumentMutex()); - getLOKitDocument()->setView(_viewId); getLOKitDocument()->setClientZoom(tilePixelWidth, tilePixelHeight, tileTwipWidth, tileTwipHeight); @@ -800,8 +780,6 @@ bool ChildSession::clientVisibleArea(const char* /*buffer*/, int /*length*/, con return false; } - std::unique_lock<std::mutex> lock(_docManager.getDocumentMutex()); - getLOKitDocument()->setView(_viewId); getLOKitDocument()->setClientVisibleArea(x, y, width, height); @@ -828,8 +806,6 @@ bool ChildSession::outlineState(const char* /*buffer*/, int /*length*/, const st bool column = type == "column"; bool hidden = state == "hidden"; - std::unique_lock<std::mutex> lock(_docManager.getDocumentMutex()); - getLOKitDocument()->setView(_viewId); getLOKitDocument()->setOutlineState(column, level, index, hidden); @@ -875,17 +851,13 @@ bool ChildSession::downloadAs(const char* /*buffer*/, int /*length*/, const std: const std::string nameAnonym = anonymizeUrl(name); const std::string urlAnonym = JAILED_DOCUMENT_ROOT + tmpDir + "/" + Poco::Path(nameAnonym).getFileName(); - { - std::unique_lock<std::mutex> lock(_docManager.getDocumentMutex()); - - LOG_DBG("Calling LOK's downloadAs with: url='" << urlAnonym << "', format='" << - (format.empty() ? "(nullptr)" : format.c_str()) << "', ' filterOptions=" << - (filterOptions.empty() ? "(nullptr)" : filterOptions.c_str()) << "'."); + LOG_DBG("Calling LOK's downloadAs with: url='" << urlAnonym << "', format='" << + (format.empty() ? "(nullptr)" : format.c_str()) << "', ' filterOptions=" << + (filterOptions.empty() ? "(nullptr)" : filterOptions.c_str()) << "'."); - getLOKitDocument()->saveAs(url.c_str(), - format.empty() ? nullptr : format.c_str(), - filterOptions.empty() ? nullptr : filterOptions.c_str()); - } + getLOKitDocument()->saveAs(url.c_str(), + format.empty() ? nullptr : format.c_str(), + filterOptions.empty() ? nullptr : filterOptions.c_str()); sendTextFrame("downloadas: jail=" + _jailId + " dir=" + tmpDir + " name=" + name + " port=" + std::to_string(ClientPortNumber) + " id=" + id); @@ -901,13 +873,10 @@ bool ChildSession::getChildId() std::string ChildSession::getTextSelectionInternal(const std::string& mimeType) { char* textSelection = nullptr; - { - std::unique_lock<std::mutex> lock(_docManager.getDocumentMutex()); - getLOKitDocument()->setView(_viewId); + getLOKitDocument()->setView(_viewId); - textSelection = getLOKitDocument()->getTextSelection(mimeType.c_str(), nullptr); - } + textSelection = getLOKitDocument()->getTextSelection(mimeType.c_str(), nullptr); std::string str(textSelection ? textSelection : ""); free(textSelection); @@ -944,8 +913,6 @@ bool ChildSession::paste(const char* buffer, int length, const std::vector<std:: const int size = length - firstLine.size() - 1; if (size > 0) { - std::unique_lock<std::mutex> lock(_docManager.getDocumentMutex()); - getLOKitDocument()->setView(_viewId); getLOKitDocument()->paste(mimeType.c_str(), data, size); @@ -1005,8 +972,6 @@ bool ChildSession::insertFile(const char* /*buffer*/, int /*length*/, const std: "\"value\":\"" + url + "\"" "}}"; - std::unique_lock<std::mutex> lock(_docManager.getDocumentMutex()); - getLOKitDocument()->setView(_viewId); LOG_TRC("Inserting graphic: '" << arguments.c_str() << "', '"); @@ -1037,7 +1002,6 @@ bool ChildSession::extTextInputEvent(const char* /*buffer*/, int /*length*/, std::string decodedText; URI::decode(text, decodedText); - std::unique_lock<std::mutex> lock(_docManager.getDocumentMutex()); getLOKitDocument()->setView(_viewId); getLOKitDocument()->postWindowExtTextInputEvent(id, type, decodedText.c_str()); @@ -1092,7 +1056,6 @@ bool ChildSession::keyEvent(const char* /*buffer*/, int /*length*/, return true; } - std::unique_lock<std::mutex> lock(_docManager.getDocumentMutex()); getLOKitDocument()->setView(_viewId); if (target == LokEventTargetEnum::Document) getLOKitDocument()->postKeyEvent(type, charcode, keycode); @@ -1132,8 +1095,6 @@ bool ChildSession::gestureEvent(const char* /*buffer*/, int /*length*/, return false; } - std::unique_lock<std::mutex> lock(_docManager.getDocumentMutex()); - getLOKitDocument()->setView(_viewId); getLOKitDocument()->postWindowGestureEvent(windowID, type.c_str(), x, y, offset); @@ -1194,8 +1155,6 @@ bool ChildSession::mouseEvent(const char* /*buffer*/, int /*length*/, return false; } - std::unique_lock<std::mutex> lock(_docManager.getDocumentMutex()); - getLOKitDocument()->setView(_viewId); switch (target) { @@ -1226,8 +1185,6 @@ bool ChildSession::unoCommand(const char* /*buffer*/, int /*length*/, const std: tokens[1] == ".uno:Redo" || Util::startsWith(tokens[1], "vnd.sun.star.script:")); - std::unique_lock<std::mutex> lock(_docManager.getDocumentMutex()); - getLOKitDocument()->setView(_viewId); if (tokens.size() == 2) @@ -1270,8 +1227,6 @@ bool ChildSession::selectText(const char* /*buffer*/, int /*length*/, const std: return false; } - std::unique_lock<std::mutex> lock(_docManager.getDocumentMutex()); - getLOKitDocument()->setView(_viewId); getLOKitDocument()->setTextSelection(type, x, y); @@ -1283,7 +1238,6 @@ bool ChildSession::renderWindow(const char* /*buffer*/, int /*length*/, const st { const unsigned winId = (tokens.size() > 1 ? std::stoul(tokens[1]) : 0); - std::unique_lock<std::mutex> lock(_docManager.getDocumentMutex()); getLOKitDocument()->setView(_viewId); int startX = 0, startY = 0; @@ -1354,7 +1308,6 @@ bool ChildSession::sendWindowCommand(const char* /*buffer*/, int /*length*/, con { const unsigned winId = (tokens.size() > 1 ? std::stoul(tokens[1]) : 0); - std::unique_lock<std::mutex> lock(_docManager.getDocumentMutex()); getLOKitDocument()->setView(_viewId); if (tokens.size() > 2 && tokens[2] == "close") @@ -1529,11 +1482,7 @@ bool ChildSession::exportSignAndUploadDocument(const char* buffer, int length, c const Poco::Path filenameParam(filename); const std::string aTempDocumentURL = JAILED_DOCUMENT_ROOT + aTempDir + "/" + filenameParam.getFileName(); - { - std::unique_lock<std::mutex> lock(_docManager.getDocumentMutex()); - - getLOKitDocument()->saveAs(aTempDocumentURL.c_str(), filetype.c_str(), nullptr); - } + getLOKitDocument()->saveAs(aTempDocumentURL.c_str(), filetype.c_str(), nullptr); // sign document { @@ -1624,8 +1573,6 @@ bool ChildSession::exportSignAndUploadDocument(const char* buffer, int length, c bool ChildSession::askSignatureStatus(const char* buffer, int length, const std::vector<std::string>& /*tokens*/) { - std::unique_lock<std::mutex> lock(_docManager.getDocumentMutex()); - bool bResult = true; const std::string firstLine = getFirstLine(buffer, length); @@ -1676,8 +1623,6 @@ bool ChildSession::selectGraphic(const char* /*buffer*/, int /*length*/, const s return false; } - std::unique_lock<std::mutex> lock(_docManager.getDocumentMutex()); - getLOKitDocument()->setView(_viewId); getLOKitDocument()->setGraphicSelection(type, x, y); @@ -1693,8 +1638,6 @@ bool ChildSession::resetSelection(const char* /*buffer*/, int /*length*/, const return false; } - std::unique_lock<std::mutex> lock(_docManager.getDocumentMutex()); - getLOKitDocument()->setView(_viewId); getLOKitDocument()->resetSelection(); @@ -1743,51 +1686,48 @@ bool ChildSession::saveAs(const char* /*buffer*/, int /*length*/, const std::vec } bool success = false; - { - std::unique_lock<std::mutex> lock(_docManager.getDocumentMutex()); - if (filterOptions.empty() && format == "html") - { - // Opt-in to avoid linked images, those would not leave the chroot. - filterOptions = "EmbedImages"; - } + if (filterOptions.empty() && format == "html") + { + // Opt-in to avoid linked images, those would not leave the chroot. + filterOptions = "EmbedImages"; + } - // We don't have the FileId at this point, just a new filename to save-as. - // So here the filename will be obfuscated with some hashing, which later will - // get a proper FileId that we will use going forward. - LOG_DBG("Calling LOK's saveAs with: '" << anonymizeUrl(wopiFilename) << "', '" << - (format.size() == 0 ? "(nullptr)" : format.c_str()) << "', '" << - (filterOptions.size() == 0 ? "(nullptr)" : filterOptions.c_str()) << "'."); + // We don't have the FileId at this point, just a new filename to save-as. + // So here the filename will be obfuscated with some hashing, which later will + // get a proper FileId that we will use going forward. + LOG_DBG("Calling LOK's saveAs with: '" << anonymizeUrl(wopiFilename) << "', '" << + (format.size() == 0 ? "(nullptr)" : format.c_str()) << "', '" << + (filterOptions.size() == 0 ? "(nullptr)" : filterOptions.c_str()) << "'."); - getLOKitDocument()->setView(_viewId); + getLOKitDocument()->setView(_viewId); - success = getLOKitDocument()->saveAs(url.c_str(), - format.empty() ? nullptr : format.c_str(), - filterOptions.empty() ? nullptr : filterOptions.c_str()); + success = getLOKitDocument()->saveAs(url.c_str(), + format.empty() ? nullptr : format.c_str(), + filterOptions.empty() ? nullptr : filterOptions.c_str()); - if (!success) + if (!success) + { + // a desperate try - add an extension hoping that it'll help + bool retry = true; + switch (getLOKitDocument()->getDocumentType()) { - // a desperate try - add an extension hoping that it'll help - bool retry = true; - switch (getLOKitDocument()->getDocumentType()) - { - case LOK_DOCTYPE_TEXT: url += ".odt"; wopiFilename += ".odt"; break; - case LOK_DOCTYPE_SPREADSHEET: url += ".ods"; wopiFilename += ".ods"; break; - case LOK_DOCTYPE_PRESENTATION: url += ".odp"; wopiFilename += ".odp"; break; - case LOK_DOCTYPE_DRAWING: url += ".odg"; wopiFilename += ".odg"; break; - default: retry = false; break; - } + case LOK_DOCTYPE_TEXT: url += ".odt"; wopiFilename += ".odt"; break; + case LOK_DOCTYPE_SPREADSHEET: url += ".ods"; wopiFilename += ".ods"; break; + case LOK_DOCTYPE_PRESENTATION: url += ".odp"; wopiFilename += ".odp"; break; + case LOK_DOCTYPE_DRAWING: url += ".odg"; wopiFilename += ".odg"; break; + default: retry = false; break; + } - if (retry) - { - LOG_DBG("Retry: calling LOK's saveAs with: '" << url.c_str() << "', '" << - (format.size() == 0 ? "(nullptr)" : format.c_str()) << "', '" << - (filterOptions.size() == 0 ? "(nullptr)" : filterOptions.c_str()) << "'."); + if (retry) + { + LOG_DBG("Retry: calling LOK's saveAs with: '" << url.c_str() << "', '" << + (format.size() == 0 ? "(nullptr)" : format.c_str()) << "', '" << + (filterOptions.size() == 0 ? "(nullptr)" : filterOptions.c_str()) << "'."); - success = getLOKitDocument()->saveAs(url.c_str(), - format.size() == 0 ? nullptr :format.c_str(), - filterOptions.size() == 0 ? nullptr : filterOptions.c_str()); - } + success = getLOKitDocument()->saveAs(url.c_str(), + format.size() == 0 ? nullptr :format.c_str(), + filterOptions.size() == 0 ? nullptr : filterOptions.c_str()); } } @@ -1813,8 +1753,6 @@ bool ChildSession::setClientPart(const char* /*buffer*/, int /*length*/, const s return false; } - std::unique_lock<std::mutex> lock(_docManager.getDocumentMutex()); - getLOKitDocument()->setView(_viewId); if (getLOKitDocument()->getDocumentType() != LOK_DOCTYPE_TEXT && part != getLOKitDocument()->getPart()) @@ -1835,8 +1773,6 @@ bool ChildSession::setPage(const char* /*buffer*/, int /*length*/, const std::ve return false; } - std::unique_lock<std::mutex> lock(_docManager.getDocumentMutex()); - getLOKitDocument()->setView(_viewId); getLOKitDocument()->setPart(page); @@ -1854,8 +1790,6 @@ bool ChildSession::renderShapeSelection(const char* /*buffer*/, int /*length*/, return false; } - std::unique_lock<std::mutex> lock(_docManager.getDocumentMutex()); - getLOKitDocument()->setView(_viewId); char* pOutput = nullptr; @@ -2079,7 +2013,6 @@ void ChildSession::loKitCallback(const int type, const std::string& payload) { //TODO: clenaup and merge. - std::unique_lock<std::mutex> lock(_docManager.getDocumentMutex()); const int parts = getLOKitDocument()->getParts(); for (int i = 0; i < parts; ++i) { @@ -2091,8 +2024,6 @@ void ChildSession::loKitCallback(const int type, const std::string& payload) " height=" + std::to_string(INT_MAX)); } - lock.unlock(); - getStatus("", 0); } break; diff --git a/kit/ChildSession.hpp b/kit/ChildSession.hpp index 597002336..215d1ad4b 100644 --- a/kit/ChildSession.hpp +++ b/kit/ChildSession.hpp @@ -68,10 +68,6 @@ public: virtual std::map<int, UserInfo> getViewInfo() = 0; virtual std::mutex& getMutex() = 0; - /// Mutex guarding the document - so that we can lock operations like - /// setting a view followed by a tile render, etc. - virtual std::mutex& getDocumentMutex() = 0; - virtual std::string getObfuscatedFileId() = 0; virtual std::shared_ptr<TileQueue>& getTileQueue() = 0; diff --git a/kit/Kit.cpp b/kit/Kit.cpp index b0f3e32c2..2f0d63f21 100644 --- a/kit/Kit.cpp +++ b/kit/Kit.cpp @@ -1021,8 +1021,6 @@ public: " passwordProvided=" << _haveDocPassword << " password='" << _docPassword << "'"); - Util::assertIsLocked(_documentMutex); - if (_isDocPasswordProtected && _haveDocPassword) { // it means this is the second attempt with the wrong password; abort the load operation @@ -1098,7 +1096,6 @@ public: const size_t pixmapSize = 4 * pixmapWidth * pixmapHeight; std::vector<unsigned char> pixmap(pixmapSize, 0); - std::unique_lock<std::mutex> lock(_documentMutex); if (!_loKitDocument) { LOG_ERR("Tile rendering requested before loading document."); @@ -1516,7 +1513,6 @@ private: const int viewId = session.getViewId(); _tileQueue->removeCursorPosition(viewId); - std::unique_lock<std::mutex> lockLokDoc(_documentMutex); if (_loKitDocument == nullptr) { LOG_ERR("Unloading session [" << sessionId << "] without loKitDocument."); @@ -1591,8 +1587,6 @@ private: /// Notify all views of viewId and their associated usernames void notifyViewInfo() override { - Util::assertIsLocked(_documentMutex); - // Get the list of view ids from the core const int viewCount = getLOKitDocument()->getViewsCount(); std::vector<int> viewIds(viewCount); @@ -1693,8 +1687,6 @@ private: // Get the color value for all author names from the core std::map<std::string, int> getViewColors() { - Util::assertIsLocked(_documentMutex); - char* values = _loKitDocument->getCommandValues(".uno:TrackedChangeAuthors"); const std::string colorValues = std::string(values == nullptr ? "" : values); std::free(values); @@ -1745,8 +1737,6 @@ private: if (!lang.empty()) options = "Language=" + lang; - std::unique_lock<std::mutex> lock(_documentMutex); - if (!_loKitDocument) { // This is the first time we are loading the document @@ -2133,12 +2123,6 @@ private: return _loKitDocument; } - /// Return access to the lok::Document instance. - std::mutex& getDocumentMutex() override - { - return _documentMutex; - } - std::string getObfuscatedFileId() override { return _obfuscatedFileId; @@ -2178,10 +2162,6 @@ private: std::atomic<bool> _stop; mutable std::mutex _mutex; - /// Mutex guarding the lok::Document so that we can lock operations - /// like setting a view followed by a tile render, etc. - std::mutex _documentMutex; - ThreadPool _pngPool; std::condition_variable _cvLoading; diff --git a/test/WhiteBoxTests.cpp b/test/WhiteBoxTests.cpp index 21ca04bd1..38bb627d0 100644 --- a/test/WhiteBoxTests.cpp +++ b/test/WhiteBoxTests.cpp @@ -542,11 +542,6 @@ public: return _mutex; } - std::mutex& getDocumentMutex() override - { - return _mutex; - } - std::string getObfuscatedFileId() override { return std::string(); _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits