iOS and Android: try more logfile locations

On some devices (e.g., a Sony Xperia phone) the GenericDataLocation is
not app writeable. Instead of just giving app, try a few other default
locations as well (and since all of these are actually string lists,
try all of the options that Qt gives us).

Reasonably, we should only set the libdivecomputer logfile name if we
found a writeable location.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This commit is contained in:
Dirk Hohndel 2018-06-28 04:54:08 -07:00
parent 1161782f3b
commit bcde65b152

View file

@ -149,27 +149,43 @@ QMLManager::QMLManager() : m_locationServiceEnabled(false),
#if defined(Q_OS_ANDROID) || defined(Q_OS_IOS) #if defined(Q_OS_ANDROID) || defined(Q_OS_IOS)
#if defined(Q_OS_ANDROID) #if defined(Q_OS_ANDROID)
appLogFileName = QStandardPaths::standardLocations(QStandardPaths::GenericDataLocation).first() + "/subsurface.log"; // on Android we first try the GenericDataLocation (typically /storage/emulated/0) and if that fails
QString libdcLogFileName = QStandardPaths::standardLocations(QStandardPaths::GenericDataLocation).first() + "/libdivecomputer.log"; // (as happened e.g. on a Sony Xperia phone) we try several other default locations, with the TempLocation as last resort
QStringList fileLocations =
QStandardPaths::standardLocations(QStandardPaths::GenericDataLocation) +
QStandardPaths::standardLocations(QStandardPaths::DocumentsLocation) +
QStandardPaths::standardLocations(QStandardPaths::DownloadLocation) +
QStandardPaths::standardLocations(QStandardPaths::TempLocation);
#elif defined(Q_OS_IOS) #elif defined(Q_OS_IOS)
// on iOS we should save the data to the DocumentsLocation so it becomes accessible to the user // on iOS we should save the data to the DocumentsLocation so it becomes accessible to the user
appLogFileName = QStandardPaths::standardLocations(QStandardPaths::DocumentsLocation).first() + "/subsurface.log"; QStringList fileLocations =
QString libdcLogFileName = QStandardPaths::standardLocations(QStandardPaths::DocumentsLocation).first() + "/libdivecomputer.log"; QStandardPaths::standardLocations(QStandardPaths::DocumentsLocation);
#endif #endif
// remove the existing libdivecomputer logfile so we don't copy an old one by mistake appLogFileOpen = false;
QFile libdcLog(libdcLogFileName); for (const QString &fileLocation : fileLocations) {
libdcLog.remove(); appLogFileName = fileLocation + "/subsurface.log";
logfile_name = copy_qstring(libdcLogFileName); appLogFile.setFileName(appLogFileName);
appLogFile.setFileName(appLogFileName); if (!appLogFile.open(QIODevice::ReadWrite|QIODevice::Truncate)) {
if (!appLogFile.open(QIODevice::ReadWrite|QIODevice::Truncate)) { appendTextToLog("Failed to open logfile " + appLogFileName
appLogFileOpen = false; + " at " + QDateTime::currentDateTime().toString()
appendTextToLog("Failed to open logfile " + appLogFileName + " error: " + appLogFile.errorString());
+ " at " + QDateTime::currentDateTime().toString() } else {
+ " error: " + appLogFile.errorString()); // found a directory that works
} else { appLogFileOpen = true;
appLogFileOpen = true; break;
}
}
if (appLogFileOpen) {
appendTextToLog("Successfully opened logfile " + appLogFileName appendTextToLog("Successfully opened logfile " + appLogFileName
+ " at " + QDateTime::currentDateTime().toString()); + " at " + QDateTime::currentDateTime().toString());
// if we were able to write the overall logfile, also write the libdivecomputer logfile
QString libdcLogFileName = appLogFileName.replace("/subsurface.log", "/libdivecomputer.log");
// remove the existing libdivecomputer logfile so we don't copy an old one by mistake
QFile libdcLog(libdcLogFileName);
libdcLog.remove();
logfile_name = copy_qstring(libdcLogFileName);
} else {
appendTextToLog("No writeable location found, in-memory log only and no libdivecomputer log");
} }
#endif #endif
LOG_STP("qmlmgr log started"); LOG_STP("qmlmgr log started");