summaryrefslogtreecommitdiffstats
path: root/src/corelib
diff options
context:
space:
mode:
authorSamuel Mira <samuel.mira@qt.io>2022-06-01 15:59:29 +0300
committerSamuel Mira <samuel.mira@qt.io>2022-06-15 06:58:00 +0000
commit16414f6d35efa9b69dcbaf3026c73018cd1aca6a (patch)
tree25d0553bb42d8af0da6c57c2adf1c4f8bca28b62 /src/corelib
parentdf1beb422aa3b773a3b07c56bd9857474e1d2f28 (diff)
Android: Fix QSettings when using content URL
Using QSettings with Content URL in Android failed because of 3 issues: * the lock file assumed that it could append ".lock" to the file name for its name * the lock file assumed that it could write in the same directory as the file * the QSaveFile used by QSettings requires direct write on content URL but setDirectWriteFallback is set to false on QSettings by default This patch fixes those issues by, when it is an Content URL in Android, saving the lock file in QStandardPaths::CacheLocation and setting the setDirectWriteFallback to true. This does not break backwards compatibility because appending ".lock" to the Content URL will always make an invalid URL, so it did not work before. Fixes: QTBUG-103455 Change-Id: I92867577507b7069e4e6091d94e0931bb6dbcbed Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> Reviewed-by: Assam Boudjelthia <assam.boudjelthia@qt.io> (cherry picked from commit 140ca89a3c2b8d78889d27217f977cd4de10041b) Reviewed-by: Marc Mutz <marc.mutz@qt.io>
Diffstat (limited to 'src/corelib')
-rw-r--r--src/corelib/io/qsettings.cpp21
1 files changed, 18 insertions, 3 deletions
diff --git a/src/corelib/io/qsettings.cpp b/src/corelib/io/qsettings.cpp
index 88768f9511..7e5d40108d 100644
--- a/src/corelib/io/qsettings.cpp
+++ b/src/corelib/io/qsettings.cpp
@@ -48,8 +48,9 @@
#define Q_XDG_PLATFORM
#endif
-#if !defined(QT_NO_STANDARDPATHS) && (defined(Q_XDG_PLATFORM) || defined(QT_PLATFORM_UIKIT))
-#define QSETTINGS_USE_QSTANDARDPATHS
+#if !defined(QT_NO_STANDARDPATHS) \
+ && (defined(Q_XDG_PLATFORM) || defined(QT_PLATFORM_UIKIT) || defined(Q_OS_ANDROID))
+# define QSETTINGS_USE_QSTANDARDPATHS
#endif
// ************************************************************************
@@ -1331,6 +1332,15 @@ void QConfFileSettingsPrivate::syncConfFile(QConfFile *confFile)
}
#ifndef QT_BOOTSTRAPPED
+ QString lockFileName = confFile->name + ".lock"_L1;
+
+# if defined(Q_OS_ANDROID) && defined(QSETTINGS_USE_QSTANDARDPATHS)
+ // On android and if it is a content URL put the lock file in a
+ // writable location to prevent permissions issues and invalid paths.
+ if (confFile->name.startsWith("content:"_L1))
+ lockFileName = QStandardPaths::writableLocation(QStandardPaths::CacheLocation)
+ + QFileInfo(lockFileName).fileName();
+# endif
/*
Use a lockfile in order to protect us against other QSettings instances
trying to write the same settings at the same time.
@@ -1338,7 +1348,7 @@ void QConfFileSettingsPrivate::syncConfFile(QConfFile *confFile)
We only need to lock if we are actually writing as only concurrent writes are a problem.
Concurrent read and write are not a problem because the writing operation is atomic.
*/
- QLockFile lockFile(confFile->name + ".lock"_L1);
+ QLockFile lockFile(lockFileName);
if (!readOnly && !lockFile.lock() && atomicSyncOnly) {
setStatus(QSettings::AccessError);
return;
@@ -1416,6 +1426,11 @@ void QConfFileSettingsPrivate::syncConfFile(QConfFile *confFile)
#if !defined(QT_BOOTSTRAPPED) && QT_CONFIG(temporaryfile)
QSaveFile sf(confFile->name);
sf.setDirectWriteFallback(!atomicSyncOnly);
+# ifdef Q_OS_ANDROID
+ // QSaveFile requires direct write when using content scheme URL in Android
+ if (confFile->name.startsWith("content:"_L1))
+ sf.setDirectWriteFallback(true);
+# endif
#else
QFile sf(confFile->name);
#endif