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 Pick-to: 6.3 6.2 Change-Id: I92867577507b7069e4e6091d94e0931bb6dbcbed Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> Reviewed-by: Assam Boudjelthia <assam.boudjelthia@qt.io>
This commit is contained in:
parent
3df23b1fe4
commit
140ca89a3c
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user