Makefile.am | 28 +-- android/README | 16 + android/lib/build.gradle | 11 - android/lib/src/main/cpp/CMakeLists.txt.in | 5 android/lib/src/main/java/org/libreoffice/androidlib/LOActivity.java | 50 ----- common/Authorization.hpp | 2 common/Protocol.cpp | 42 ---- common/Protocol.hpp | 23 ++ common/Util.cpp | 19 ++ common/Util.hpp | 91 +++++++++- configure.ac | 61 +++++- ios/GEN2.txt | 4 loleaflet/css/mobilewizard.css | 1 loleaflet/images/note.svg | 63 ++++++ loleaflet/reference.html | 15 - loleaflet/src/control/Control.DocumentNameInput.js | 2 loleaflet/src/control/Control.JSDialogBuilder.js | 1 loleaflet/src/control/Control.Toolbar.js | 7 loleaflet/src/core/Socket.js | 4 loleaflet/src/map/Map.js | 4 test/Makefile.am | 2 test/WopiProofTests.cpp | 15 + wsd/Admin.cpp | 26 +- wsd/ClientSession.cpp | 14 - wsd/ClientSession.hpp | 1 wsd/DocumentBroker.cpp | 23 ++ wsd/DocumentBroker.hpp | 8 wsd/LOOLWSD.cpp | 24 -- wsd/LOOLWSD.hpp | 3 wsd/Storage.cpp | 1 wsd/Storage.hpp | 11 + 31 files changed, 380 insertions(+), 197 deletions(-)
New commits: commit 89afba185a3464110cf73e3f3f04db1cb41d15cd Author: Szymon Kłos <[email protected]> AuthorDate: Thu Jul 2 08:58:53 2020 +0200 Commit: Tor Lillqvist <[email protected]> CommitDate: Thu Jul 2 16:20:47 2020 +0300 jsdialog: use listbox for font size selector with newer core version it changed a name Change-Id: I3804f9f6e1acfc96123e4376aeb3b040deeebe4c Reviewed-on: https://gerrit.libreoffice.org/c/online/+/97707 Tested-by: Jenkins Tested-by: Jenkins CollaboraOffice <[email protected]> Reviewed-by: Szymon Kłos <[email protected]> diff --git a/loleaflet/src/control/Control.JSDialogBuilder.js b/loleaflet/src/control/Control.JSDialogBuilder.js index ba6ee8fce..41ad87376 100644 --- a/loleaflet/src/control/Control.JSDialogBuilder.js +++ b/loleaflet/src/control/Control.JSDialogBuilder.js @@ -1414,6 +1414,7 @@ L.Control.JSDialogBuilder = L.Control.extend({ if (data.id === 'applystyle' || data.id === 'fontnamecombobox' || data.id === 'fontsizecombobox' || + data.id === 'fontsize' || data.id === 'FontBox') { builder._listboxControl(parentContainer, data, builder); } else if (data.id === 'searchterm' || commit db914a859fafccd255db075856d2d2560e8ec0b5 Author: Tor Lillqvist <[email protected]> AuthorDate: Thu Jul 2 15:39:12 2020 +0300 Commit: Tor Lillqvist <[email protected]> CommitDate: Thu Jul 2 16:20:39 2020 +0300 Update the first step Won't bother with renaming the Objective-C classes I think, just to keep changes minimal. Change-Id: I683479fc32275a5ee2a1bc9c28275bc887c42474 diff --git a/ios/GEN2.txt b/ios/GEN2.txt index 4ab55b990..e6b1b1204 100644 --- a/ios/GEN2.txt +++ b/ios/GEN2.txt @@ -28,8 +28,8 @@ Ideas: Steps: -- Rename the Objective-C files/classes to have a CO prefix. Reduces - risk of confusion with C++ classes. +- Re-factorings that don't affect any working of current Online or + apps, but which will make the iOS app re-plumbing easier. - ... commit 9af9e38f28ab7acee5efbeb884d3d8845aaced86 Author: Mike Kaganski <[email protected]> AuthorDate: Wed Jul 1 13:38:06 2020 +0300 Commit: Tor Lillqvist <[email protected]> CommitDate: Thu Jul 2 16:20:32 2020 +0300 Only lock documents in editing sessions Change-Id: I97753541a944bb299b04c032790d6af7a9ee0f63 Reviewed-on: https://gerrit.libreoffice.org/c/online/+/97609 Tested-by: Jenkins Tested-by: Jenkins CollaboraOffice <[email protected]> Reviewed-by: Mike Kaganski <[email protected]> diff --git a/wsd/DocumentBroker.cpp b/wsd/DocumentBroker.cpp index 7753d87ac..e64c0f8e1 100644 --- a/wsd/DocumentBroker.cpp +++ b/wsd/DocumentBroker.cpp @@ -786,7 +786,9 @@ bool DocumentBroker::load(const std::shared_ptr<ClientSession>& session, const s std::string localPath = _storage->loadStorageFileToLocal( session->getAuthorization(), session->getCookies(), *_lockCtx, templateSource); - if (!_storage->updateLockState(session->getAuthorization(), session->getCookies(), *_lockCtx, true)) + // Only lock the document on storage for editing sessions + if (!session->isReadOnly() && + !_storage->updateLockState(session->getAuthorization(), session->getCookies(), *_lockCtx, true)) LOG_ERR("Failed to lock!"); #if !MOBILEAPP commit bfd8760ca39285e68f1b2cf39ae19bf3e21fc6f3 Author: Mike Kaganski <[email protected]> AuthorDate: Thu Jul 2 10:54:59 2020 +0300 Commit: Tor Lillqvist <[email protected]> CommitDate: Thu Jul 2 16:20:25 2020 +0300 tdf#134041: add a unit test Change-Id: Ic040adb7a2a73635041146f6d6425db1b02c2e61 Reviewed-on: https://gerrit.libreoffice.org/c/online/+/97721 Tested-by: Jenkins Tested-by: Mike Kaganski <[email protected]> Reviewed-by: Michael Meeks <[email protected]> diff --git a/test/WopiProofTests.cpp b/test/WopiProofTests.cpp index 3e4aa5418..cfa1f57dc 100644 --- a/test/WopiProofTests.cpp +++ b/test/WopiProofTests.cpp @@ -137,6 +137,21 @@ void WopiProofTests::testOurProof() int64_t ticks = std::stoll(timestamp.c_str(), nullptr, 10); verifySignature(access_token, uri, ticks, modulus, exponent, proof); + + // tdf#134041: test another data + + access_token = "~!@#$%^&*()_+`1234567890-="; + uri = "https://[email protected]:12345/blah?query_string=bar"; + pairs = gen.GetProofHeaders(access_token, uri); + len = pairs.size(); + LOK_ASSERT_EQUAL(2, len); + LOK_ASSERT_EQUAL(pairs[0].first, std::string("X-WOPI-TimeStamp")); + timestamp = pairs[0].second; + LOK_ASSERT_EQUAL(pairs[1].first, std::string("X-WOPI-Proof")); + proof = pairs[1].second; + + ticks = std::stoll(timestamp.c_str(), nullptr, 10); + verifySignature(access_token, uri, ticks, modulus, exponent, proof); } CPPUNIT_TEST_SUITE_REGISTRATION(WopiProofTests); commit c73241ac178a9ed07b71658d691a091784110bb8 Author: Jan Holesovsky <[email protected]> AuthorDate: Thu Jul 2 09:28:31 2020 +0200 Commit: Tor Lillqvist <[email protected]> CommitDate: Thu Jul 2 16:20:18 2020 +0300 android: Default to building just the simple case: armeabi-v7a... ... unless more builddirs are provided in --with-lo-builddir, separated by colons. Change-Id: I49946cd932ec22804ecb51aba86f3dae2aba05f5 Reviewed-on: https://gerrit.libreoffice.org/c/online/+/97672 Tested-by: Jenkins Reviewed-by: Jan Holesovsky <[email protected]> diff --git a/configure.ac b/configure.ac index ff78941ef..2fd403c52 100644 --- a/configure.ac +++ b/configure.ac @@ -368,7 +368,7 @@ fi # to the Mac. # Android: We need these to setup the CMakeLists.txt properly. LOBUILDDIR= -ANDROID_ABI= +ANDROID_ABI="armeabi-v7a" LOBUILDDIR_ARM64_V8A= LOBUILDDIR_X86= LOBUILDDIR_X86_64= @@ -385,10 +385,12 @@ CORE_VERSION_HASH="" if test \( "$enable_iosapp" = "yes" -a `uname -s` = "Darwin" \) -o \( "$enable_androidapp" = "yes" \); then if test "$enable_androidapp" = "yes" ; then AC_MSG_CHECKING([for Android ABI to build for]) - if test -z "$with_android_abi" ; then - ANDROID_ABI="armeabi-v7a arm64-v8a x86 x86_64" - else + if test -n "$with_android_abi" ; then ANDROID_ABI=`echo $with_android_abi | sed 's/:/ /g'` + else + if echo "$with_lo_builddir" | grep -qs ':' ; then + ANDROID_ABI="armeabi-v7a arm64-v8a x86 x86_64" + fi fi AC_MSG_RESULT([$ANDROID_ABI]) fi commit 2992e4ffb0a73f5d6d647c72ec44fc9134746c20 Author: Jan Holesovsky <[email protected]> AuthorDate: Thu Jul 2 10:15:20 2020 +0200 Commit: Tor Lillqvist <[email protected]> CommitDate: Thu Jul 2 16:20:10 2020 +0300 android: Remove unneeded dependency + add some comments. Change-Id: Idbc271a398f6f0c037d478bda5ee0b149ca4f24f Reviewed-on: https://gerrit.libreoffice.org/c/online/+/97730 Tested-by: Jenkins CollaboraOffice <[email protected]> Tested-by: Jenkins Reviewed-by: Jan Holesovsky <[email protected]> diff --git a/android/lib/src/main/cpp/CMakeLists.txt.in b/android/lib/src/main/cpp/CMakeLists.txt.in index 2e1a5fdb8..4c4e1344a 100644 --- a/android/lib/src/main/cpp/CMakeLists.txt.in +++ b/android/lib/src/main/cpp/CMakeLists.txt.in @@ -5,7 +5,6 @@ add_library(androidapp SHARED androidapp.cpp ../../../../../common/Authorization.cpp ../../../../../common/FileUtil.cpp - ../../../../../common/JailUtil.cpp ../../../../../common/Log.cpp ../../../../../common/MessageQueue.cpp ../../../../../common/Protocol.cpp diff --git a/common/Authorization.hpp b/common/Authorization.hpp index 14accb236..b92b0d565 100644 --- a/common/Authorization.hpp +++ b/common/Authorization.hpp @@ -16,7 +16,7 @@ #include <Poco/Net/HTTPRequest.h> #include <Poco/URI.h> -/// Class to keep the authorization data. +/// Class to keep the authorization data, which can be either access_token or access_header. class Authorization { public: diff --git a/wsd/ClientSession.hpp b/wsd/ClientSession.hpp index 8922b924e..cc153bdd8 100644 --- a/wsd/ClientSession.hpp +++ b/wsd/ClientSession.hpp @@ -226,6 +226,7 @@ private: /// URI with which client made request to us const Poco::URI _uriPublic; + /// Authorization data - either access_token or access_header. const Authorization _auth; /// The cookies we should pass on to the storage on saving. commit 4781e351bc1bbc02c2995dd9d3d626a7b90819a3 Author: Szymon Kłos <[email protected]> AuthorDate: Thu Jul 2 08:58:06 2020 +0200 Commit: Tor Lillqvist <[email protected]> CommitDate: Thu Jul 2 16:20:03 2020 +0300 mobilewizard: add bottom padding Change-Id: Ie1ae026a580c483f1a0a9cffffdd8eaac8679dca Reviewed-on: https://gerrit.libreoffice.org/c/online/+/97706 Tested-by: Jenkins CollaboraOffice <[email protected]> Tested-by: Jenkins Reviewed-by: Szymon Kłos <[email protected]> diff --git a/loleaflet/css/mobilewizard.css b/loleaflet/css/mobilewizard.css index 9cbad6825..00e915a6c 100644 --- a/loleaflet/css/mobilewizard.css +++ b/loleaflet/css/mobilewizard.css @@ -194,6 +194,7 @@ p.mobile-wizard.ui-combobox-text.selected { top: 111px; bottom: 0px; width: 100%; + padding-bottom: 50px; } #mobile-wizard.funcwizard div#mobile-wizard-content.hideHelpBG { background: none !important; commit e17903bad0f8c26b7e600a7faaca884de9d2f26e Author: Tomaž Vajngerl <[email protected]> AuthorDate: Thu Jul 2 10:22:24 2020 +0200 Commit: Tor Lillqvist <[email protected]> CommitDate: Thu Jul 2 16:19:55 2020 +0300 add missing note image Change-Id: Iebeac73a517d853c85d81856b9c64e18adc1e4ad diff --git a/loleaflet/images/note.svg b/loleaflet/images/note.svg new file mode 100644 index 000000000..2c7236a0c --- /dev/null +++ b/loleaflet/images/note.svg @@ -0,0 +1,63 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + inkscape:version="1.0 (4035a4fb49, 2020-05-01)" + sodipodi:docname="note.svg" + id="svg8" + version="1.1" + viewBox="0 0 32 32"> + <metadata + id="metadata14"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + </cc:Work> + </rdf:RDF> + </metadata> + <defs + id="defs12" /> + <sodipodi:namedview + inkscape:current-layer="svg8" + inkscape:window-maximized="0" + inkscape:window-y="23" + inkscape:window-x="26" + inkscape:cy="48.22105" + inkscape:cx="1.6214117" + inkscape:zoom="6.600599" + showgrid="false" + id="namedview10" + inkscape:window-height="1016" + inkscape:window-width="960" + inkscape:pageshadow="2" + inkscape:pageopacity="0" + guidetolerance="10" + gridtolerance="10" + objecttolerance="10" + borderopacity="1" + bordercolor="#666666" + pagecolor="#ffffff" /> + <g + style="stroke:#000000;stroke-opacity:1;fill:#eac282;fill-opacity:1" + id="g6" + fill-rule="evenodd"> + <path + style="stroke:#000000;stroke-opacity:1;fill:#eac282;fill-opacity:1" + id="path2" + fill="#3a3a38" + d="m3.5 3a.50005.50005 0 0 0 -.5.5v19a.50005.50005 0 0 0 .5.5h4.5v5.5a.50005.50005 0 0 0 .8261719.378906l6.8593751-5.878906h12.814453a.50005.50005 0 0 0 .5-.5v-19a.50005.50005 0 0 0 -.5-.5z" /> + <path + style="stroke:#000000;stroke-opacity:1;fill:#eac282;fill-opacity:1" + id="path4" + fill="#fafafa" + d="m4 4v18h4.5a.50005.50005 0 0 1 .5.5v4.912109l6.173828-5.291015a.50005.50005 0 0 1 .326172-.121094h12.5v-18z" /> + </g> +</svg> commit f254196ee890421365c4d6b6af2299fc84e7ca1f Author: Jan Holesovsky <[email protected]> AuthorDate: Wed Jul 1 21:05:42 2020 +0200 Commit: Tor Lillqvist <[email protected]> CommitDate: Thu Jul 2 16:19:44 2020 +0300 android: No need to copy fonts from system any more. After the update of fontconfig, the hack to not to use the Noto fonts is not needed any more, they load quickly now. Change-Id: Iebd2c944e9fcc04d6976002f24a3a47f0b49f2ad Reviewed-on: https://gerrit.libreoffice.org/c/online/+/97659 Tested-by: Jenkins Tested-by: Jenkins CollaboraOffice <[email protected]> Reviewed-by: Jan Holesovsky <[email protected]> diff --git a/android/lib/src/main/java/org/libreoffice/androidlib/LOActivity.java b/android/lib/src/main/java/org/libreoffice/androidlib/LOActivity.java index 5074d637a..8465ff5e1 100644 --- a/android/lib/src/main/java/org/libreoffice/androidlib/LOActivity.java +++ b/android/lib/src/main/java/org/libreoffice/androidlib/LOActivity.java @@ -203,54 +203,6 @@ public class LOActivity extends AppCompatActivity { } } - /** - * Copies fonts except the NotoSans from the system to our location. - * This is necessary because the NotoSans is huge and fontconfig needs - * ages to parse them. - */ - private static boolean copyFonts(String fromPath, String targetDir) { - try { - File target = new File(targetDir); - if (!target.exists()) - target.mkdirs(); - - File from = new File(fromPath); - File[] files = from.listFiles(); - for (File fontFile : files) { - String fontFileName = fontFile.getName(); - if (!fontFileName.equals("Roboto-Regular.ttf")) { - Log.i(TAG, "Ignored font file: " + fontFile); - continue; - } else { - Log.i(TAG, "Copying font file: " + fontFile); - } - - // copy the font file over - InputStream in = new FileInputStream(fontFile); - try { - OutputStream out = new FileOutputStream(targetDir + "/" + fontFile.getName()); - try { - byte[] buffer = new byte[4096]; - int len; - while ((len = in.read(buffer)) > 0) { - out.write(buffer, 0, len); - } - } finally { - out.close(); - } - } finally { - in.close(); - } - } - } catch (Exception e) { - e.printStackTrace(); - Log.e(TAG, "copyFonts failed: " + e.getMessage()); - return false; - } - - return true; - } - private Handler getMainHandler() { if (mMainHandler == null) { mMainHandler = new Handler(getMainLooper()); @@ -289,7 +241,7 @@ public class LOActivity extends AppCompatActivity { @Override protected Void doInBackground(Void... voids) { // copy the new assets - if (copyFromAssets(getAssets(), "unpack", getApplicationInfo().dataDir) && copyFonts("/system/fonts", getApplicationInfo().dataDir + "/user/fonts")) { + if (copyFromAssets(getAssets(), "unpack", getApplicationInfo().dataDir)) { sPrefs.edit().putString(ASSETS_EXTRACTED_GIT_COMMIT, BuildConfig.GIT_COMMIT).apply(); } return null; commit 53373f28044e630f71f8d742e081f5686b3f64a7 Author: Jan Holesovsky <[email protected]> AuthorDate: Wed Jul 1 20:41:41 2020 +0200 Commit: Tor Lillqvist <[email protected]> CommitDate: Thu Jul 2 16:19:36 2020 +0300 android: Use the system fonts. Now that we have upgraded the fontconfig to a version that can process the Noto fonts in reasonable time, use them. Change-Id: I7e46bef6827f5e257a0d583137aa9a26c2a22ed3 Reviewed-on: https://gerrit.libreoffice.org/c/online/+/97658 Tested-by: Jenkins CollaboraOffice <[email protected]> Tested-by: Jenkins Reviewed-by: Jan Holesovsky <[email protected]> diff --git a/android/lib/build.gradle b/android/lib/build.gradle index c3b3621b9..8882d8e5d 100644 --- a/android/lib/build.gradle +++ b/android/lib/build.gradle @@ -117,17 +117,6 @@ task copyUnpackAssets(type: Copy) { String line -> line.replaceAll( '@@APPLICATION_ID@@', new String("${liboApplicationId}") - ).replaceAll( - // FIXME Avoid the Android system fonts for the moment, - // the huge Noto Sans fonts have terrible impact on the 1st - // start performance. - // The real solution would be to either make fontconfig - // faster, or at least find a way to avoid only the Noto - // Sans, or present a progressbar or something. - // For the moment, we just copy the Roboto font (needed - // for the dialogs; see LOActivity.copyFonts()) and - // remove the system fonts from the config. - '<dir>/system/fonts</dir>', new String("") ) } } commit 83c4f8786c9eb1451708ed3ff3166bcf6dbb1870 Author: Ashod Nakashian <[email protected]> AuthorDate: Thu Jun 25 21:53:26 2020 -0400 Commit: Tor Lillqvist <[email protected]> CommitDate: Thu Jul 2 16:19:27 2020 +0300 leaflet: set renameFilename before saving There is a race between the time we set the renameFilename value and the uno:Save response arrives. If renameFilename is not set by then we miss the opportunity to rename and instead simply end up saving the file. Change-Id: I8d7acbc95cef264de4385d506bfa34458ba80283 Reviewed-on: https://gerrit.libreoffice.org/c/online/+/97189 Tested-by: Jenkins CollaboraOffice <[email protected]> Tested-by: Jenkins Reviewed-by: Ashod Nakashian <[email protected]> diff --git a/loleaflet/src/control/Control.DocumentNameInput.js b/loleaflet/src/control/Control.DocumentNameInput.js index cfc4e5998..3ad053094 100644 --- a/loleaflet/src/control/Control.DocumentNameInput.js +++ b/loleaflet/src/control/Control.DocumentNameInput.js @@ -27,8 +27,8 @@ L.Control.DocumentNameInput = L.Control.extend({ // same extension, just rename the file // file name must be without the extension for rename value = value.substr(0, value.lastIndexOf('.')); + this.map._renameFilename = value; this.map.sendUnoCommand('.uno:Save'); - this.map._RenameFile = value; } } } else { diff --git a/loleaflet/src/control/Control.Toolbar.js b/loleaflet/src/control/Control.Toolbar.js index 1eccdce82..e8dce9bc3 100644 --- a/loleaflet/src/control/Control.Toolbar.js +++ b/loleaflet/src/control/Control.Toolbar.js @@ -924,9 +924,10 @@ function onCommandResult(e) { map._everModified = true; // document is saved for rename - if (map._RenameFile) { - map.renameFile(map._RenameFile); - map._RenameFile = ''; + if (map._renameFilename) { + var renameFilename = map._renameFilename; + map._renameFilename = ''; + map.renameFile(renameFilename); } } var postMessageObj = { diff --git a/loleaflet/src/map/Map.js b/loleaflet/src/map/Map.js index 5f9882a53..285e4954d 100644 --- a/loleaflet/src/map/Map.js +++ b/loleaflet/src/map/Map.js @@ -259,8 +259,8 @@ L.Map = L.Evented.extend({ // This becomes true if document was ever modified by the user this._everModified = false; - // This becomes new file name if document is renamed which used later on uno:Save result - this._RenameFile = ''; + // This is the new file name, if the document is renamed, which is used on uno:Save's result. + this._renameFilename = ''; // Document is completely loaded or not this._docLoaded = false; commit e8f4add4e712f83ca7f7dba9404ee9b3da455ee8 Author: Ashod Nakashian <[email protected]> AuthorDate: Tue Jun 2 18:19:23 2020 -0400 Commit: Tor Lillqvist <[email protected]> CommitDate: Thu Jul 2 16:19:19 2020 +0300 wsd: move string-to-integer helper to Util Improved implementation. Change-Id: I0b426f8742c8b718f8c939d271f6645a8ed466d4 Reviewed-on: https://gerrit.libreoffice.org/c/online/+/96374 Tested-by: Jenkins CollaboraOffice <[email protected]> Tested-by: Jenkins Reviewed-by: Ashod Nakashian <[email protected]> diff --git a/common/Protocol.cpp b/common/Protocol.cpp index 771b87b49..d02f2d340 100644 --- a/common/Protocol.cpp +++ b/common/Protocol.cpp @@ -48,48 +48,6 @@ namespace LOOLProtocol return std::make_tuple(major, minor, patch); } - bool stringToInteger(const std::string& input, int& value) - { - try - { - value = std::stoi(input); - } - catch (std::invalid_argument&) - { - return false; - } - - return true; - } - - bool stringToUInt32(const std::string& input, uint32_t& value) - { - try - { - value = std::stoul(input); - } - catch (std::invalid_argument&) - { - return false; - } - - return true; - } - - bool stringToUInt64(const std::string& input, uint64_t& value) - { - try - { - value = std::stoull(input); - } - catch (std::invalid_argument&) - { - return false; - } - - return true; - } - bool getTokenInteger(const std::string& token, const std::string& name, int& value) { if (token.size() > (name.size() + 1) && diff --git a/common/Protocol.hpp b/common/Protocol.hpp index 5eb90941b..367d9ff27 100644 --- a/common/Protocol.hpp +++ b/common/Protocol.hpp @@ -41,9 +41,26 @@ namespace LOOLProtocol // Negative numbers for error. std::tuple<int, int, std::string> ParseVersion(const std::string& version); - bool stringToInteger(const std::string& input, int& value); - bool stringToUInt32(const std::string& input, uint32_t& value); - bool stringToUInt64(const std::string& input, uint64_t& value); + inline bool stringToInteger(const std::string& input, int& value) + { + bool res; + std::tie(value, res) = Util::i32FromString(input); + return res; + } + + inline bool stringToUInt32(const std::string& input, uint32_t& value) + { + bool res; + std::tie(value, res) = Util::i32FromString(input); + return res; + } + + inline bool stringToUInt64(const std::string& input, uint64_t& value) + { + bool res; + std::tie(value, res) = Util::u64FromString(input); + return res; + } inline bool parseNameValuePair(const std::string& token, std::string& name, std::string& value, const char delim = '=') diff --git a/common/Util.hpp b/common/Util.hpp index 28ec5154a..c634801fb 100644 --- a/common/Util.hpp +++ b/common/Util.hpp @@ -13,6 +13,7 @@ #include <cerrno> #include <cinttypes> #include <cstddef> +#include <cstdint> #include <cstring> #include <atomic> #include <functional> @@ -22,6 +23,7 @@ #include <sstream> #include <string> #include <map> +#include <utility> #include <inttypes.h> #include <memory.h> @@ -1134,10 +1136,86 @@ int main(int argc, char**argv) */ std::map<std::string, std::string> stringVectorToMap(std::vector<std::string> sVector, const char delimiter); - #if !MOBILEAPP - // If OS is not mobile, it must be Linux. - std::string getLinuxVersion(); - #endif +#if !MOBILEAPP + // If OS is not mobile, it must be Linux. + std::string getLinuxVersion(); +#endif + + /// Convert a string to 32-bit signed int. + /// Returs the parsed value and a boolean indiciating success or failure. + inline std::pair<std::int32_t, bool> i32FromString(const std::string& input) + { + const char* str = input.data(); + char* endptr = nullptr; + const auto value = std::strtol(str, &endptr, 10); + return std::make_pair(value, endptr > str && errno != ERANGE); + } + + /// Convert a string to 32-bit signed int. On failure, returns the default + /// value, and sets the bool to false (to signify that parsing had failed). + inline std::pair<std::int32_t, bool> i32FromString(const std::string& input, + const std::int32_t def) + { + const auto pair = i32FromString(input); + return pair.second ? pair : std::make_pair(def, false); + } + + /// Convert a string to 32-bit unsigned int. + /// Returs the parsed value and a boolean indiciating success or failure. + inline std::pair<std::uint32_t, bool> u32FromString(const std::string& input) + { + const char* str = input.data(); + char* endptr = nullptr; + const auto value = std::strtoul(str, &endptr, 10); + return std::make_pair(value, endptr > str && errno != ERANGE); + } + + /// Convert a string to 32-bit usigned int. On failure, returns the default + /// value, and sets the bool to false (to signify that parsing had failed). + inline std::pair<std::uint32_t, bool> u32FromString(const std::string& input, + const std::uint32_t def) + { + const auto pair = u32FromString(input); + return pair.second ? pair : std::make_pair(def, false); + } + + /// Convert a string to 64-bit signed int. + /// Returs the parsed value and a boolean indiciating success or failure. + inline std::pair<std::int64_t, bool> i64FromString(const std::string& input) + { + const char* str = input.data(); + char* endptr = nullptr; + const auto value = std::strtol(str, &endptr, 10); + return std::make_pair(value, endptr > str && errno != ERANGE); + } + + /// Convert a string to 64-bit signed int. On failure, returns the default + /// value, and sets the bool to false (to signify that parsing had failed). + inline std::pair<std::int64_t, bool> i64FromString(const std::string& input, + const std::int64_t def) + { + const auto pair = i64FromString(input); + return pair.second ? pair : std::make_pair(def, false); + } + + /// Convert a string to 64-bit unsigned int. + /// Returs the parsed value and a boolean indiciating success or failure. + inline std::pair<std::uint64_t, bool> u64FromString(const std::string& input) + { + const char* str = input.data(); + char* endptr = nullptr; + const auto value = std::strtoul(str, &endptr, 10); + return std::make_pair(value, endptr > str && errno != ERANGE); + } + + /// Convert a string to 64-bit usigned int. On failure, returns the default + /// value, and sets the bool to false (to signify that parsing had failed). + inline std::pair<std::uint64_t, bool> u64FromString(const std::string& input, + const std::uint64_t def) + { + const auto pair = u64FromString(input); + return pair.second ? pair : std::make_pair(def, false); + } } // end namespace Util commit 140f80b2a2887c302460de68a26becd47f13ae9e Author: Ashod Nakashian <[email protected]> AuthorDate: Sat Jun 27 16:56:51 2020 -0400 Commit: Tor Lillqvist <[email protected]> CommitDate: Thu Jul 2 16:18:50 2020 +0300 wsd: admin: don't poll rapidly when cleanup is disabled When per_document.cleanup is disabled, the time between the last cleanup (which never happened) grows indefinitely, which results in minimal polling time intervals. This wastes valuable cpu cycles unnecessarily. When cleanup is disabled, there is no need to calculate the next cleanup time. The maximum is reasonable (although it should really be infinity). Change-Id: I71d065441c4c2ff96fe31e6a45a5ecfdd2f85d49 Reviewed-on: https://gerrit.libreoffice.org/c/online/+/97471 Tested-by: Jenkins Tested-by: Jenkins CollaboraOffice <[email protected]> Reviewed-by: Ashod Nakashian <[email protected]> diff --git a/wsd/Admin.cpp b/wsd/Admin.cpp index c2f665cd4..a9b87cba4 100644 --- a/wsd/Admin.cpp +++ b/wsd/Admin.cpp @@ -415,14 +415,12 @@ Admin::~Admin() void Admin::pollingThread() { - std::chrono::steady_clock::time_point lastCPU, lastMem, lastNet, lastCleanup; - _model.setThreadOwner(std::this_thread::get_id()); - lastCPU = std::chrono::steady_clock::now(); - lastMem = lastCPU; - lastNet = lastCPU; - lastCleanup = lastCPU; + std::chrono::steady_clock::time_point lastCPU = std::chrono::steady_clock::now(); + std::chrono::steady_clock::time_point lastMem = lastCPU; + std::chrono::steady_clock::time_point lastNet = lastCPU; + std::chrono::steady_clock::time_point lastCleanup = lastCPU; while (!isStop() && !SigUtil::getTerminationFlag() && !SigUtil::getShutdownRequestFlag()) { @@ -484,14 +482,15 @@ void Admin::pollingThread() lastNet = now; } - int cleanupWait = _cleanupIntervalMs - - std::chrono::duration_cast<std::chrono::milliseconds>(now - lastCleanup).count(); - if (cleanupWait <= MinStatsIntervalMs / 2) // Close enough + int cleanupWait = _cleanupIntervalMs; + if (_defDocProcSettings.getCleanupSettings().getEnable()) { - if (_defDocProcSettings.getCleanupSettings().getEnable()) + cleanupWait + -= std::chrono::duration_cast<std::chrono::milliseconds>(now - lastCleanup).count(); + if (cleanupWait <= MinStatsIntervalMs / 2) // Close enough { cleanupResourceConsumingDocs(); - + cleanupWait += _cleanupIntervalMs; lastCleanup = now; } @@ -509,7 +508,8 @@ void Admin::pollingThread() } // Handle websockets & other work. - const int timeout = capAndRoundInterval(std::min(std::min(std::min(cpuWait, memWait), netWait), cleanupWait)); + const int timeout = capAndRoundInterval( + std::min(std::min(std::min(cpuWait, memWait), netWait), cleanupWait)); LOG_TRC("Admin poll for " << timeout << "ms."); poll(timeout * 1000); // continue with ms for admin, settings etc. } commit eaf15c98efd4ee7acb3016806c7577cc8434de62 Author: Ashod Nakashian <[email protected]> AuthorDate: Wed Jul 1 13:06:46 2020 -0400 Commit: Tor Lillqvist <[email protected]> CommitDate: Thu Jul 2 16:18:41 2020 +0300 make: improve cleanup dependency graph Change-Id: I8a7edd3b49a272cb7bd8bff4d91b189a5856c5c8 Reviewed-on: https://gerrit.libreoffice.org/c/online/+/97647 Tested-by: Jenkins CollaboraOffice <[email protected]> Tested-by: Jenkins Reviewed-by: Ashod Nakashian <[email protected]> diff --git a/Makefile.am b/Makefile.am index 0eba81cf5..074f05376 100644 --- a/Makefile.am +++ b/Makefile.am @@ -329,14 +329,25 @@ SYSTEM_STAMP = @SYSTEMPLATE_PATH@/system_stamp CAPABILITIES = $(if @ENABLE_SETCAP@,true,false) RUN_GDB = $(if $(GDB_FRONTEND),$(GDB_FRONTEND),gdb --tui --args) -$(SYSTEM_STAMP) : ${top_srcdir}/loolwsd-systemplate-setup - if test -s ./loolwsd; then ./loolwsd --cleanup; fi +# Add caps to the binaries that need them. +caps_bins: loolforkit loolmount +if ENABLE_SETCAP + sudo @SETCAP@ cap_fowner,cap_mknod,cap_sys_chroot=ep loolforkit + sudo @SETCAP@ cap_sys_admin=ep loolmount +else + echo "Skipping capability setting" +endif + +# Build loolwsd and loolmount first, so we can cleanup before updating +# the systemplate directory, which we can't rm if it's mounted. +$(SYSTEM_STAMP): ${top_srcdir}/loolwsd-systemplate-setup loolwsd caps_bins + $(CLEANUP_COMMAND) if test "z@SYSTEMPLATE_PATH@" != "z"; then rm -rf "@SYSTEMPLATE_PATH@"; fi ${top_srcdir}/loolwsd-systemplate-setup "@SYSTEMPLATE_PATH@" "@LO_PATH@" && touch $@ -@JAILS_PATH@ : - mkdir -p $@ +@JAILS_PATH@: $(CLEANUP_COMMAND) + mkdir -p $@ clean-local: $(CLEANUP_COMMAND) @@ -464,16 +475,7 @@ endif # installing the RPM or Debian package. .PHONY: caps_bins -caps_bins: loolforkit loolmount -if ENABLE_SETCAP - sudo @SETCAP@ cap_fowner,cap_mknod,cap_sys_chroot=ep loolforkit - sudo @SETCAP@ cap_sys_admin=ep loolmount -else - echo "Skipping capability setting" -endif - all-local: loolwsd caps_bins @JAILS_PATH@ $(SYSTEM_STAMP) - $(CLEANUP_COMMAND) # just run the build without any tests build-nocheck: all-am diff --git a/test/Makefile.am b/test/Makefile.am index c12038b0d..327832f79 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -309,3 +309,5 @@ all-local: unittest @echo @fc-cache "@LO_PATH@"/share/fonts/truetype @UNITTEST=1 ${top_builddir}/test/unittest + echo "Done test all-local" + $(CLEANUP_COMMAND) commit 417ccb6923f82d48e549a3c4be916ecc9f781926 Author: Samuel Mehrbrodt <[email protected]> AuthorDate: Wed Jul 1 12:46:58 2020 +0200 Commit: Tor Lillqvist <[email protected]> CommitDate: Thu Jul 2 16:18:31 2020 +0300 tdf#131123 Report back real save result 665b1629de30a4a402c6b10dd542de158db1f428 was not correct, as it reported back the save result of the internal save (which usually succeeds). Instead we want to know the save result of the remote storage (WOPI/Webdav). So report that back instead. Change-Id: Iaaa42b8c817a19c2c77935a6f81c1951fdf2216c Reviewed-on: https://gerrit.libreoffice.org/c/online/+/97637 Tested-by: Jenkins Reviewed-by: Samuel Mehrbrodt <[email protected]> diff --git a/loleaflet/reference.html b/loleaflet/reference.html index b52d34688..99cae5ec6 100644 --- a/loleaflet/reference.html +++ b/loleaflet/reference.html @@ -3040,18 +3040,21 @@ Editor to WOPI host <td><code> <nobr>success: <boolean></nobr> <nobr>result: <string></nobr> + <nobr>errorMsg: <string></nobr> </code></td> <td>Acknowledgement when save finishes.<br/> + <i>This response is only emitted if <code>Notify</code> parameter + is mentioned by <code>Action_Save</code> PostMessage API.</i> + <br/> <code>success</code> tells if LOOL was able to save the document - successfully. When this is false, then another - parameter, <code>result</code> is present which contains the - reason that document was not saved. + successfully.<br/> + <code>result</code> contains the reason the document was not saved.<br/> In case, document was not saved because it was not modified, then this parameter contains the string 'unmodified'. In this case, WOPI hosts can be sure that there are no changes pending - in the document to be saved to the storage. - This response is only emitted if <code>Notify</code> parameter - is mentioned by <code>Action_Save</code> PostMessage API. + in the document to be saved to the storage.<br/> + <code>errorMsg</code> contains a detailed error message in case saving failed. + Probably it will contain the error message returned from the WOPI/Webdav host. </td> </tr> <tr> diff --git a/loleaflet/src/core/Socket.js b/loleaflet/src/core/Socket.js index 5a5568424..c3798a774 100644 --- a/loleaflet/src/core/Socket.js +++ b/loleaflet/src/core/Socket.js @@ -365,7 +365,9 @@ L.Socket = L.Class.extend({ } var postMessageObj = { - success: commandresult['success'] + success: commandresult['success'], + result: commandresult['result'], + errorMsg: commandresult['errorMsg'] }; this._map.fire('postMessage', {msgId: 'Action_Save_Resp', args: postMessageObj}); } diff --git a/wsd/ClientSession.cpp b/wsd/ClientSession.cpp index 859052ea4..b313742ec 100644 --- a/wsd/ClientSession.cpp +++ b/wsd/ClientSession.cpp @@ -553,11 +553,8 @@ bool ClientSession::_handleInput(const char *buffer, int length) constexpr bool isAutosave = false; constexpr bool isExitSave = false; - bool result = docBroker->sendUnoSave(getId(), dontTerminateEdit != 0, dontSaveIfUnmodified != 0, + docBroker->sendUnoSave(getId(), dontTerminateEdit != 0, dontSaveIfUnmodified != 0, isAutosave, isExitSave, extendedData); - std::string resultstr = result ? "true" : "false"; - std::string msg = "commandresult: { \"command\": \"save\", \"success\": " + resultstr + " }"; - docBroker->broadcastMessage(msg); } } else if (tokens.equals(0, "savetostorage")) @@ -566,10 +563,7 @@ bool ClientSession::_handleInput(const char *buffer, int length) if (tokens.size() > 1) getTokenInteger(tokens[1], "force", force); - bool result = docBroker->saveToStorage(getId(), true, "" /* This is irrelevant when success is true*/, true); - std::string resultstr = result ? "true" : "false"; - std::string msg = "commandresult: { \"command\": \"savetostorage\", \"success\": " + resultstr + " }"; - docBroker->broadcastMessage(msg); + docBroker->saveToStorage(getId(), true, "" /* This is irrelevant when success is true*/, true); } else if (tokens.equals(0, "clientvisiblearea")) { diff --git a/wsd/DocumentBroker.cpp b/wsd/DocumentBroker.cpp index 8a41a6dd9..7753d87ac 100644 --- a/wsd/DocumentBroker.cpp +++ b/wsd/DocumentBroker.cpp @@ -969,6 +969,7 @@ bool DocumentBroker::saveToStorageInternal(const std::string& sessionId, bool su LOG_DBG("Save skipped as document [" << _docKey << "] was not modified."); _lastSaveTime = std::chrono::steady_clock::now(); _poll->wakeup(); + broadcastSaveResult(true, "unmodified"); return true; } @@ -978,6 +979,7 @@ bool DocumentBroker::saveToStorageInternal(const std::string& sessionId, bool su LOG_ERR("Session with sessionId [" << sessionId << "] not found while storing document docKey [" << _docKey << "]. The document will not be uploaded to storage at this time."); + broadcastSaveResult(false, "Session not found"); return false; } @@ -986,6 +988,7 @@ bool DocumentBroker::saveToStorageInternal(const std::string& sessionId, bool su { LOG_ERR("Cannot store docKey [" << _docKey << "] as .uno:Save has failed in LOK."); it->second->sendTextFrameAndLogError("error: cmd=storage kind=savefailed"); + broadcastSaveResult(false, "Could not save document in LibreOfficeKit"); return false; } @@ -1021,6 +1024,7 @@ bool DocumentBroker::saveToStorageInternal(const std::string& sessionId, bool su LOG_DBG("Skipping unnecessary saving to URI [" << uriAnonym << "] with docKey [" << _docKey << "]. File last modified " << timeInSec.count() << " seconds ago, timestamp unchanged."); _poll->wakeup(); + broadcastSaveResult(true, "unmodified"); return true; } @@ -1103,12 +1107,14 @@ bool DocumentBroker::saveToStorageInternal(const std::string& sessionId, bool su { sessionIt.second->sendTextFrameAndLogError("error: cmd=storage kind=savediskfull"); } + broadcastSaveResult(false, "Disk full", storageSaveResult.getErrorMsg()); } else if (storageSaveResult.getResult() == StorageBase::SaveResult::UNAUTHORIZED) { LOG_ERR("Cannot save docKey [" << _docKey << "] to storage URI [" << uriAnonym << "]. Invalid or expired access token. Notifying client."); it->second->sendTextFrameAndLogError("error: cmd=storage kind=saveunauthorized"); + broadcastSaveResult(false, "Invalid or expired access token", storageSaveResult.getErrorMsg()); } else if (storageSaveResult.getResult() == StorageBase::SaveResult::FAILED) { @@ -1117,6 +1123,7 @@ bool DocumentBroker::saveToStorageInternal(const std::string& sessionId, bool su std::ostringstream oss; oss << "error: cmd=storage kind=" << (isRename ? "renamefailed" : "savefailed"); it->second->sendTextFrame(oss.str()); + broadcastSaveResult(false, "Save failed", storageSaveResult.getErrorMsg()); } else if (storageSaveResult.getResult() == StorageBase::SaveResult::DOC_CHANGED || storageSaveResult.getResult() == StorageBase::SaveResult::CONFLICT) @@ -1127,11 +1134,23 @@ bool DocumentBroker::saveToStorageInternal(const std::string& sessionId, bool su = isModified() ? "error: cmd=storage kind=documentconflict" : "close: documentconflict"; broadcastMessage(message); + broadcastSaveResult(false, "Conflict: Document changed in storage", storageSaveResult.getErrorMsg()); } return false; } +void DocumentBroker::broadcastSaveResult(bool success, const std::string& result, const std::string& errorMsg) +{ + std::string resultstr = success ? "true" : "false"; + // Some sane limit, otherwise we get problems transfering this to the client with large strings (can be a whole webpage) + std::string errorMsgFormatted = errorMsg.substr(0, 1000); + // Replace reserverd characters + errorMsgFormatted = Poco::translate(errorMsgFormatted, "\"", "'"); + broadcastMessage("commandresult: { \"command\": \"save\", \"success\": " + resultstr + + ", \"result\": \"" + result + "\", \"errorMsg\": \"" + errorMsgFormatted + "\"}"); +} + void DocumentBroker::setLoaded() { if (!_isLoaded) diff --git a/wsd/DocumentBroker.hpp b/wsd/DocumentBroker.hpp index 4d09dff32..ce5bf7b7d 100644 --- a/wsd/DocumentBroker.hpp +++ b/wsd/DocumentBroker.hpp @@ -335,6 +335,14 @@ private: const std::string& saveAsFilename = std::string(), const bool isRename = false, const bool force = false); + /** + * Report back the save result to PostMessage users (Action_Save_Resp) + * @param success: Whether saving was successful + * @param result: Short message why saving was (not) successful + * @param errorMsg: Long error msg (Error message from WOPI host if any) + */ + void broadcastSaveResult(bool success, const std::string& result = "", const std::string& errorMsg = ""); + /// True iff a save is in progress (requested but not completed). bool isSaving() const { return _lastSaveResponseTime < _lastSaveRequestTime; } diff --git a/wsd/Storage.cpp b/wsd/Storage.cpp index 0d616f23c..e15f1abcb 100644 --- a/wsd/Storage.cpp +++ b/wsd/Storage.cpp @@ -1048,6 +1048,7 @@ WopiStorage::saveLocalFileToStorage(const Authorization& auth, const std::string std::ostringstream oss; Poco::StreamCopier::copyStream(rs, oss); std::string responseString = oss.str(); + saveResult.setErrorMsg(responseString); const std::string wopiLog(isSaveAs ? "WOPI::PutRelativeFile" : (isRename ? "WOPI::RenameFile":"WOPI::PutFile")); diff --git a/wsd/Storage.hpp b/wsd/Storage.hpp index 8f07b9229..d087fb174 100644 --- a/wsd/Storage.hpp +++ b/wsd/Storage.hpp @@ -132,10 +132,21 @@ public: return _saveAsUrl; } + void setErrorMsg(const std::string &msg) + { + _errorMsg = msg; + } + + const std::string &getErrorMsg() const + { + return _errorMsg; + } + private: Result _result; std::string _saveAsName; std::string _saveAsUrl; + std::string _errorMsg; }; enum class LOOLStatusCode commit c43910880afeb1192a7e6ac3a93afd456b97f2b2 Author: Jan Holesovsky <[email protected]> AuthorDate: Wed Jul 1 11:10:01 2020 +0200 Commit: Tor Lillqvist <[email protected]> CommitDate: Thu Jul 2 16:18:18 2020 +0300 android: Add support for x86 ABI too. Turns out that the ChromeOS uses the x86 Android runtime, not x86-64. Change-Id: Ic3b6f7a65d35d2298daa731f46e57068eaf2583d Reviewed-on: https://gerrit.libreoffice.org/c/online/+/97607 Tested-by: Jenkins Reviewed-by: Jan Holesovsky <[email protected]> diff --git a/android/README b/android/README index 7223e121e..5cffa4b4f 100644 --- a/android/README +++ b/android/README @@ -68,6 +68,22 @@ build the native parts on Windows. # install PATH="$PATH":~/Android/Sdk/ndk-bundle/toolchains/llvm/prebuilt/linux-x86_64/bin make -j8 ANDROID_ABI=arm64-v8a CC=aarch64-linux-android21-clang CXX=aarch64-linux-android21-clang++ SYSLIBS=-static-libstdc++ install INSTALLDIR=/opt/poco-android-64bit +* Poco for x86 (if you want to add the support for that into the APK too): + + # checkout the 1.10.1 in yet another location + git clone https://github.com/pocoproject/poco poco-android-x86 + cd poco-android-x86 + git checkout -b poco-1.10.1 origin/poco-1.10.1 + + # configure + ./configure --config=Android --no-samples --no-tests --omit=Crypto,NetSSL_OpenSSL,Zip,Data,Data/SQLite,Data/ODBC,Data/MySQL,MongoDB,PDF,CppParser,PageCompiler,JWT + + # build + PATH="$PATH":~/Android/Sdk/ndk-bundle/toolchains/llvm/prebuilt/linux-x86_64/bin make -j8 ANDROID_ABI=x86 CC=i686-linux-android21-clang CXX=i686-linux-android21-clang++ SYSLIBS=-static-libstdc++ + + # install + PATH="$PATH":~/Android/Sdk/ndk-bundle/toolchains/llvm/prebuilt/linux-x86_64/bin make -j8 ANDROID_ABI=x86 CC=i686-linux-android21-clang CXX=i686-linux-android21-clang++ SYSLIBS=-static-libstdc++ install INSTALLDIR=/opt/poco-android-x86 + * Poco for x86_64 (if you want to add the support for that into the APK too): # checkout the 1.10.1 in yet another location diff --git a/android/lib/src/main/cpp/CMakeLists.txt.in b/android/lib/src/main/cpp/CMakeLists.txt.in index 53a3fafd7..2e1a5fdb8 100644 --- a/android/lib/src/main/cpp/CMakeLists.txt.in +++ b/android/lib/src/main/cpp/CMakeLists.txt.in @@ -37,6 +37,10 @@ elseif(${ANDROID_ABI} STREQUAL "arm64-v8a") set(LOBUILDDIR_ABI @LOBUILDDIR_ARM64_V8A@) set(POCOINCLUDE_ABI @POCOINCLUDE_ARM64_V8A@) set(POCOLIB_ABI @POCOLIB_ARM64_V8A@) +elseif(${ANDROID_ABI} STREQUAL "x86") + set(LOBUILDDIR_ABI @LOBUILDDIR_X86@) + set(POCOINCLUDE_ABI @POCOINCLUDE_X86@) + set(POCOLIB_ABI @POCOLIB_X86@) elseif(${ANDROID_ABI} STREQUAL "x86_64") set(LOBUILDDIR_ABI @LOBUILDDIR_X86_64@) set(POCOINCLUDE_ABI @POCOINCLUDE_X86_64@) diff --git a/configure.ac b/configure.ac index 7a8177e91..ff78941ef 100644 --- a/configure.ac +++ b/configure.ac @@ -168,12 +168,14 @@ AC_ARG_WITH(android-package-versioncode, AC_ARG_WITH(android-abi, AS_HELP_STRING([--with-android-abi=x86_64], - [Allows specification of a concrete ABI that is to be built for. By default, builds for all the 3 - supported ABIs at the same time: armeabi-v7a, arm64-v8a and x86_64. + [Allows specification of a concrete ABI that is to be built for, defaults to armeabi-v7a + (when only one build dir is provided in --with-lo-builddir) or to all 4 supported ABIs at + the same time (when there are more builddirs provided in --with-lo-builddir, separated + by colons). The supported ABIs are: armeabi-v7a, arm64-v8a, x86 and x86_64. Please note that you need to specify the parameters for --with-lo-builddir, - --with-poco-includes and --with-poco-libs in the order of armeabi-v7a:arm64-v8a:x86_64. For - example, when you use --with-android-abi=x86_64, - you have to specify --with-lo-builddir=::/path/to/x86-64/builddir]), + --with-poco-includes and --with-poco-libs in the order of armeabi-v7a:arm64-v8a:x86:x86_64. + For example, when you use --with-android-abi=x86_64, + you have to specify --with-lo-builddir=:::/path/to/x86-64/builddir]), ,) AC_ARG_WITH([app-name], @@ -368,12 +370,15 @@ fi LOBUILDDIR= ANDROID_ABI= LOBUILDDIR_ARM64_V8A= +LOBUILDDIR_X86= LOBUILDDIR_X86_64= POCOINCLUDE= POCOINCLUDE_ARM64_V8A= +POCOINCLUDE_X86= POCOINCLUDE_X86_64= POCOLIB= POCOLIB_ARM64_V8A= +POCOLIB_X86= POCOLIB_X86_64= POCODEBUG= CORE_VERSION_HASH="" @@ -381,7 +386,7 @@ if test \( "$enable_iosapp" = "yes" -a `uname -s` = "Darwin" \) -o \( "$enable_a if test "$enable_androidapp" = "yes" ; then AC_MSG_CHECKING([for Android ABI to build for]) if test -z "$with_android_abi" ; then - ANDROID_ABI="armeabi-v7a arm64-v8a x86_64" + ANDROID_ABI="armeabi-v7a arm64-v8a x86 x86_64" else ANDROID_ABI=`echo $with_android_abi | sed 's/:/ /g'` fi @@ -398,7 +403,8 @@ if test \( "$enable_iosapp" = "yes" -a `uname -s` = "Darwin" \) -o \( "$enable_a if echo "$LOBUILDDIR" | grep -qs ':' ; then LOBUILDDIR=`echo $with_lo_builddir | cut -d: -f1` LOBUILDDIR_ARM64_V8A=`echo $with_lo_builddir | cut -d: -f2` - LOBUILDDIR_X86_64=`echo $with_lo_builddir | cut -d: -f3` + LOBUILDDIR_X86=`echo $with_lo_builddir | cut -d: -f3` + LOBUILDDIR_X86_64=`echo $with_lo_builddir | cut -d: -f4` fi fi @@ -420,6 +426,14 @@ if test \( "$enable_iosapp" = "yes" -a `uname -s` = "Darwin" \) -o \( "$enable_a fi fi + if test -n "$LOBUILDDIR_X86" ; then + if test -f "$LOBUILDDIR_X86/workdir/LinkTarget/StaticLibrary/liblibpng.a" ; then + AC_MSG_RESULT([$LOBUILDDIR_X86]) + else + AC_MSG_ERROR([This is not a LibreOffice x86 core build directory: $LOBUILDDIR_X86]) + fi + fi + if test -n "$LOBUILDDIR_X86_64" ; then if test -f "$LOBUILDDIR_X86_64/workdir/LinkTarget/StaticLibrary/liblibpng.a" ; then AC_MSG_RESULT([$LOBUILDDIR_X86_64]) @@ -438,7 +452,8 @@ if test \( "$enable_iosapp" = "yes" -a `uname -s` = "Darwin" \) -o \( "$enable_a if echo "$POCOINCLUDE" | grep -qs ':' ; then POCOINCLUDE=`echo $with_poco_includes | cut -d: -f1` POCOINCLUDE_ARM64_V8A=`echo $with_poco_includes | cut -d: -f2` - POCOINCLUDE_X86_64=`echo $with_poco_includes | cut -d: -f3` + POCOINCLUDE_X86=`echo $with_poco_includes | cut -d: -f3` + POCOINCLUDE_X86_64=`echo $with_poco_includes | cut -d: -f4` fi fi @@ -457,6 +472,14 @@ if test \( "$enable_iosapp" = "yes" -a `uname -s` = "Darwin" \) -o \( "$enable_a fi fi + if test -n "$POCOINCLUDE_X86" ; then + if test -f "$POCOINCLUDE_X86/Poco/Poco.h"; then + AC_MSG_RESULT([$POCOINCLUDE_X86]) + else + AC_MSG_ERROR([This is not a Poco x86 include directory: $POCOINCLUDE_X86]) + fi + fi + if test -n "$POCOINCLUDE_X86_64" ; then if test -f "$POCOINCLUDE_X86_64/Poco/Poco.h"; then AC_MSG_RESULT([$POCOINCLUDE_X86_64]) @@ -475,7 +498,8 @@ if test \( "$enable_iosapp" = "yes" -a `uname -s` = "Darwin" \) -o \( "$enable_a if echo "$POCOLIB" | grep -qs ':' ; then POCOLIB=`echo $with_poco_libs | cut -d: -f1` POCOLIB_ARM64_V8A=`echo $with_poco_libs | cut -d: -f2` - POCOLIB_X86_64=`echo $with_poco_libs | cut -d: -f3` + POCOLIB_X86=`echo $with_poco_libs | cut -d: -f3` + POCOLIB_X86_64=`echo $with_poco_libs | cut -d: -f4` fi fi @@ -494,6 +518,14 @@ if test \( "$enable_iosapp" = "yes" -a `uname -s` = "Darwin" \) -o \( "$enable_a fi fi + if test -n "$POCOLIB_X86" ; then + if test -f "$POCOLIB_X86/libPocoFoundation.a"; then + AC_MSG_RESULT([$POCOLIB_X86]) + else + AC_MSG_ERROR([This is not a Poco x86 lib directory: $POCOLIB_X86]) + fi + fi + if test -n "$POCOLIB_X86_64" ; then if test -f "$POCOLIB_X86_64/libPocoFoundation.a"; then AC_MSG_RESULT([$POCOLIB_X86_64]) @@ -509,12 +541,15 @@ fi AC_SUBST(LOBUILDDIR) AC_SUBST(ANDROID_ABI) AC_SUBST(LOBUILDDIR_ARM64_V8A) +AC_SUBST(LOBUILDDIR_X86) AC_SUBST(LOBUILDDIR_X86_64) AC_SUBST(POCOINCLUDE) AC_SUBST(POCOINCLUDE_ARM64_V8A) +AC_SUBST(POCOINCLUDE_X86) AC_SUBST(POCOINCLUDE_X86_64) AC_SUBST(POCOLIB) AC_SUBST(POCOLIB_ARM64_V8A) +AC_SUBST(POCOLIB_X86) AC_SUBST(POCOLIB_X86_64) AC_SUBST(POCODEBUG) AC_SUBST([CORE_VERSION_HASH]) commit 68479ccdb49bfc2285ef39738b8dbfedcd095d07 Author: Tor Lillqvist <[email protected]> AuthorDate: Thu Jul 2 15:36:50 2020 +0300 Commit: Tor Lillqvist <[email protected]> CommitDate: Thu Jul 2 16:03:48 2020 +0300 Slight refactoring to make planned re-plumbing of iOS app easier Change-Id: I274cf167c6593de6f073301f7071f2173b40cbab diff --git a/common/Util.cpp b/common/Util.cpp index 16681cc56..e0ce00250 100644 --- a/common/Util.cpp +++ b/common/Util.cpp @@ -60,6 +60,7 @@ #include "Common.hpp" #include "Log.hpp" +#include "Protocol.hpp" #include "Util.hpp" using std::size_t; @@ -640,6 +641,24 @@ namespace Util hash.resize(std::min(8, (int)hash.length())); } + std::string getProcessIdentifier() + { + static std::string id = Util::rng::getHexString(8); + + return id; + } + + std::string getVersionJSON() + { + std::string version, hash; + Util::getVersionInfo(version, hash); + return + "{ \"Version\": \"" + version + "\", " + "\"Hash\": \"" + hash + "\", " + "\"Protocol\": \"" + LOOLProtocol::GetProtocolVersion() + "\", " + "\"Id\": \"" + Util::getProcessIdentifier() + "\" }"; + } + std::string UniqueId() { static std::atomic_int counter(0); diff --git a/common/Util.hpp b/common/Util.hpp index ba70cba47..28ec5154a 100644 --- a/common/Util.hpp +++ b/common/Util.hpp @@ -174,6 +174,11 @@ namespace Util /// Get version information void getVersionInfo(std::string& version, std::string& hash); + ///< A random hash that identifies the current process. + std::string getProcessIdentifier(); + + std::string getVersionJSON(); + /// Return a string that is unique across processes and calls. std::string UniqueId(); diff --git a/wsd/Admin.cpp b/wsd/Admin.cpp index 996e7b75c..c2f665cd4 100644 --- a/wsd/Admin.cpp +++ b/wsd/Admin.cpp @@ -117,7 +117,7 @@ void AdminSocketHandler::handleMessage(const std::vector<char> &payload) else if (tokens.equals(0, "version")) { // Send LOOL version information - sendTextFrame("loolserver " + LOOLWSD::getVersionJSON()); + sendTextFrame("loolserver " + Util::getVersionJSON()); // Send LOKit version information sendTextFrame("lokitversion " + LOOLWSD::LOKitVersion); } diff --git a/wsd/ClientSession.cpp b/wsd/ClientSession.cpp index 5f79a07fa..859052ea4 100644 --- a/wsd/ClientSession.cpp +++ b/wsd/ClientSession.cpp @@ -216,7 +216,7 @@ std::string ClientSession::getClipboardURI(bool encode) std::string meta = _serverURL.getSubURLForEndpoint( "/lool/clipboard?WOPISrc=" + encodedFrom + - "&ServerId=" + LOOLWSD::HostIdentifier + + "&ServerId=" + Util::getProcessIdentifier() + "&ViewId=" + std::to_string(getKitViewId()) + "&Tag=" + _clipboardKeys[0]); @@ -363,7 +363,7 @@ bool ClientSession::_handleInput(const char *buffer, int length) } // Send LOOL version information - sendTextFrame("loolserver " + LOOLWSD::getVersionJSON()); + sendTextFrame("loolserver " + Util::getVersionJSON()); // Send LOKit version information sendTextFrame("lokitversion " + LOOLWSD::LOKitVersion); diff --git a/wsd/LOOLWSD.cpp b/wsd/LOOLWSD.cpp index 6efb55655..c75bc37ef 100644 --- a/wsd/LOOLWSD.cpp +++ b/wsd/LOOLWSD.cpp @@ -720,7 +720,6 @@ std::string LOOLWSD::FileServerRoot; std::string LOOLWSD::WelcomeFilesRoot; std::string LOOLWSD::ServiceRoot; std::string LOOLWSD::LOKitVersion; -std::string LOOLWSD::HostIdentifier; std::string LOOLWSD::ConfigFile = LOOLWSD_CONFIGDIR "/loolwsd.xml"; std::string LOOLWSD::ConfigDir = LOOLWSD_CONFIGDIR "/conf.d"; std::string LOOLWSD::LogLevel = "trace"; @@ -2685,7 +2684,7 @@ private: if (it != DocBrokers.end()) docBroker = it->second; } - if (docBroker && serverId == LOOLWSD::HostIdentifier) + if (docBroker && serverId == Util::getProcessIdentifier()) { std::shared_ptr<std::string> data; DocumentBroker::ClipboardRequest type; @@ -2729,8 +2728,8 @@ private: " and broker: " << (docBroker ? "" : "not ") << "found"); std::string errMsg; - if (serverId != LOOLWSD::HostIdentifier) - errMsg = "Cluster configuration error: mis-matching serverid " + serverId + " vs. " + LOOLWSD::HostIdentifier; + if (serverId != Util::getProcessIdentifier()) + errMsg = "Cluster configuration error: mis-matching serverid " + serverId + " vs. " + Util::getProcessIdentifier(); else errMsg = "Empty clipboard item / session tag " + tag; @@ -3542,7 +3541,7 @@ public: << "\n WelcomeFilesRoot: " << LOOLWSD::WelcomeFilesRoot << "\n ServiceRoot: " << LOOLWSD::ServiceRoot << "\n LOKitVersion: " << LOOLWSD::LOKitVersion - << "\n HostIdentifier: " << LOOLWSD::HostIdentifier + << "\n HostIdentifier: " << Util::getProcessIdentifier() << "\n ConfigFile: " << LOOLWSD::ConfigFile << "\n ConfigDir: " << LOOLWSD::ConfigDir << "\n LogLevel: " << LOOLWSD::LogLevel @@ -3704,17 +3703,6 @@ private: } }; -std::string LOOLWSD::getVersionJSON() -{ - std::string version, hash; - Util::getVersionInfo(version, hash); - return - "{ \"Version\": \"" + version + "\", " - "\"Hash\": \"" + hash + "\", " - "\"Protocol\": \"" + GetProtocolVersion() + "\", " - "\"Id\": \"" + HostIdentifier + "\" }"; -} - static LOOLWSDServer srv; #if !MOBILEAPP @@ -3740,11 +3728,9 @@ int LOOLWSD::innerMain() setenv("LD_BIND_NOW", "1", 1); # endif - HostIdentifier = Util::rng::getHexString(8); - std::string version, hash; Util::getVersionInfo(version, hash); - LOG_INF("Loolwsd version details: " << version << " - " << hash << " - id " << HostIdentifier << " - on " << Util::getLinuxVersion()); + LOG_INF("Loolwsd version details: " << version << " - " << hash << " - id " << Util::getProcessIdentifier() << " - on " << Util::getLinuxVersion()); #endif initializeSSL(); diff --git a/wsd/LOOLWSD.hpp b/wsd/LOOLWSD.hpp index 654546d30..6f697f28a 100644 --- a/wsd/LOOLWSD.hpp +++ b/wsd/LOOLWSD.hpp @@ -241,7 +241,6 @@ public: static std::string WelcomeFilesRoot; ///< From where we should serve the release notes (or otherwise useful content) that is shown on first install or version update. static std::string ServiceRoot; ///< There are installations that need prefixing every page with some path. static std::string LOKitVersion; - static std::string HostIdentifier; ///< A unique random hash that identifies this server static std::string LogLevel; static bool AnonymizeUserData; static bool CheckLoolUser; @@ -396,8 +395,6 @@ public: /// get correct server URL with protocol + port number for this running server static std::string getServerURL(); - static std::string getVersionJSON(); - int innerMain(); protected: _______________________________________________ Libreoffice-commits mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
