Commit a552bc72 authored by Nate Weibley's avatar Nate Weibley

Fix force close issues on android by enforcing queued connections on the QStringListModel

parent 3c0c2607
...@@ -21,15 +21,18 @@ This file is part of the QGROUNDCONTROL project ...@@ -21,15 +21,18 @@ This file is part of the QGROUNDCONTROL project
======================================================================*/ ======================================================================*/
// Allows QGlobalStatic to work on this translation unit
#define _LOG_CTOR_ACCESS_ public
#include "AppMessages.h" #include "AppMessages.h"
#include <QFile> #include <QFile>
#include <QStringListModel> #include <QStringListModel>
#include <QtConcurrent> #include <QtConcurrent>
#include <QTextStream> #include <QTextStream>
AppLogModel AppLogModel::instance; Q_GLOBAL_STATIC(AppLogModel, debug_model)
static QtMessageHandler old_handler; static QtMessageHandler old_handler;
static AppLogModel &debug_strings = AppLogModel::getModel();
static void msgHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg) static void msgHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{ {
...@@ -38,9 +41,7 @@ static void msgHandler(QtMsgType type, const QMessageLogContext &context, const ...@@ -38,9 +41,7 @@ static void msgHandler(QtMsgType type, const QMessageLogContext &context, const
// Avoid recursion // Avoid recursion
if (!QString(context.category).startsWith("qt.quick")) { if (!QString(context.category).startsWith("qt.quick")) {
const int line = debug_strings.rowCount(); debug_model->log(output);
debug_strings.insertRows(line, 1);
debug_strings.setData(debug_strings.index(line), output, Qt::DisplayRole);
} }
if (old_handler != nullptr) { if (old_handler != nullptr) {
...@@ -52,20 +53,24 @@ static void msgHandler(QtMsgType type, const QMessageLogContext &context, const ...@@ -52,20 +53,24 @@ static void msgHandler(QtMsgType type, const QMessageLogContext &context, const
void AppMessages::installHandler() void AppMessages::installHandler()
{ {
old_handler = qInstallMessageHandler(msgHandler); old_handler = qInstallMessageHandler(msgHandler);
}
AppLogModel *AppMessages::getModel() // Force creation of debug model on installing thread
{ Q_UNUSED(*debug_model);
return &AppLogModel::getModel();
} }
AppLogModel& AppLogModel::getModel() AppLogModel *AppMessages::getModel()
{ {
return instance; return debug_model;
} }
AppLogModel::AppLogModel() : QStringListModel() AppLogModel::AppLogModel() : QStringListModel()
{ {
#ifdef __mobile__
Qt::ConnectionType contype = Qt::QueuedConnection;
#else
Qt::ConnectionType contype = Qt::AutoConnection;
#endif
connect(this, &AppLogModel::emitLog, this, &AppLogModel::threadsafeLog, contype);
} }
void AppLogModel::writeMessages(const QUrl dest_file) void AppLogModel::writeMessages(const QUrl dest_file)
...@@ -73,7 +78,7 @@ void AppLogModel::writeMessages(const QUrl dest_file) ...@@ -73,7 +78,7 @@ void AppLogModel::writeMessages(const QUrl dest_file)
const QString writebuffer(stringList().join('\n').append('\n')); const QString writebuffer(stringList().join('\n').append('\n'));
QtConcurrent::run([dest_file, writebuffer] { QtConcurrent::run([dest_file, writebuffer] {
emit instance.writeStarted(); emit debug_model->writeStarted();
bool success = false; bool success = false;
QFile file(dest_file.toLocalFile()); QFile file(dest_file.toLocalFile());
if (file.open(QIODevice::WriteOnly | QIODevice::Text)) { if (file.open(QIODevice::WriteOnly | QIODevice::Text)) {
...@@ -81,6 +86,18 @@ void AppLogModel::writeMessages(const QUrl dest_file) ...@@ -81,6 +86,18 @@ void AppLogModel::writeMessages(const QUrl dest_file)
out << writebuffer; out << writebuffer;
success = out.status() == QTextStream::Ok; success = out.status() == QTextStream::Ok;
} }
emit instance.writeFinished(success); emit debug_model->writeFinished(success);
}); });
} }
void AppLogModel::log(const QString message)
{
emit debug_model->emitLog(message);
}
void AppLogModel::threadsafeLog(const QString message)
{
const int line = rowCount();
insertRows(line, 1);
setData(index(line), message, Qt::DisplayRole);
}
...@@ -27,21 +27,28 @@ This file is part of the QGROUNDCONTROL project ...@@ -27,21 +27,28 @@ This file is part of the QGROUNDCONTROL project
#include <QStringListModel> #include <QStringListModel>
#include <QUrl> #include <QUrl>
// Hackish way to force only this translation unit to have public ctor access
#ifndef _LOG_CTOR_ACCESS_
#define _LOG_CTOR_ACCESS_ private
#endif
class AppLogModel : public QStringListModel class AppLogModel : public QStringListModel
{ {
Q_OBJECT Q_OBJECT
public: public:
static AppLogModel& getModel();
Q_INVOKABLE void writeMessages(const QUrl dest_file); Q_INVOKABLE void writeMessages(const QUrl dest_file);
static void log(const QString message);
signals: signals:
void emitLog(const QString message);
void writeStarted(); void writeStarted();
void writeFinished(bool success); void writeFinished(bool success);
private: private slots:
void threadsafeLog(const QString message);
_LOG_CTOR_ACCESS_:
AppLogModel(); AppLogModel();
static AppLogModel instance;
}; };
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment