GUI user applications: improvements

This commit is contained in:
Nicolas Mailloux 2022-06-18 09:26:52 -04:00
parent 763279f1f1
commit 0cf2bca0d3
8 changed files with 140 additions and 115 deletions

View file

@ -336,7 +336,12 @@ void apps::showUserApps(bool showDisabledJson)
}
else {
QString function = __func__; log(function + ": JSON is invalid", className);
emit showToast("ERROR: Failed to parse 'apps.json'");
ui->editUserAppsBtn->deleteLater();
ui->label_6->deleteLater();
ui->horizontalLayout->deleteLater();
ui->line_2->deleteLater();
ui->line_3->deleteLater();
}
}

View file

@ -13,6 +13,12 @@
#include <QDebug>
#include <QRandomGenerator>
#include <QDateTime>
#include <QDirIterator>
#include <QJsonDocument>
#include <QJsonParseError>
#include <QJsonObject>
#include <QJsonValue>
#include <QJsonArray>
#include <stdio.h>
#include <fcntl.h>
@ -853,6 +859,90 @@ namespace {
return false;
}
}
void updateUserAppsMainJsonFile() {
QDirIterator appsDir("/mnt/onboard/onboard/.apps", QDirIterator::NoIteratorFlags);
QFile newJsonFile = QFile{"/mnt/onboard/onboard/.apps/apps.json"};
QJsonDocument newJsonDocument;
QJsonArray array;
while (appsDir.hasNext())
{
QDir dir(appsDir.next());
if(dir.exists() == true) {
if(dir.path().split("/").last().contains(".") == false) {
QFile jsonSmall = QFile{dir.path() + "/app.json"};
if(jsonSmall.exists() == true) {
jsonSmall.open(QIODevice::ReadOnly | QIODevice::Text);
QString jsonString = jsonSmall.readAll();
jsonSmall.close();
QJsonDocument jsonSmallDoc = QJsonDocument::fromJson(jsonString.toUtf8());
if(jsonSmallDoc["app"].isObject() == true) {
QJsonObject jsonSmallMainObj = jsonSmallDoc["app"].toObject();
array.append(jsonSmallMainObj);
}
else {
log("Error: User application '" + appsDir.path() + "''s JSON file descriptor is missing main object 'app'", "main");
}
}
else {
QString message = "User application '" + appsDir.path() + "' does not contain any 'app.json' file: ";
message.append(jsonSmall.fileName());
log(message, "main");
}
}
}
}
// https://forum.qt.io/topic/104791/how-i-can-create-json-format-in-qt/5
QJsonObject root;
root["list"] = array;
newJsonDocument.setObject(root);
newJsonFile.open(QFile::WriteOnly | QFile::Text | QFile::Truncate);
newJsonFile.write(newJsonDocument.toJson());
newJsonFile.flush();
newJsonFile.close();
}
void updateUserAppsSmallJsonFiles() {
QFile jsonFile = QFile{"/mnt/onboard/onboard/.apps/apps.json"};
jsonFile.open(QIODevice::ReadOnly | QIODevice::Text);
QString fileRead = jsonFile.readAll();
jsonFile.close();
QJsonDocument jsonDocument = QJsonDocument::fromJson(fileRead.toUtf8());
if(jsonDocument["list"].isArray() == true) {
QJsonArray jsonArray = jsonDocument["list"].toArray();
for(QJsonValueRef refJsonObject: jsonArray) {
QJsonObject jsonMainObject = refJsonObject.toObject();
QString appName = jsonMainObject["Name"].toString();
// This needs to be here and not at the beggining of this function because it is an iterator
QDirIterator appsDir("/mnt/onboard/onboard/.apps", QDirIterator::NoIteratorFlags);
while (appsDir.hasNext()) {
QDir dir(appsDir.next());
if(dir.exists() == true) {
if(dir.path().split("/").last().toLower().contains(appName.toLower()) == true) {
QJsonObject root;
root["app"] = refJsonObject.toObject();;
QJsonDocument newJsonDocument;
newJsonDocument.setObject(root);
QFile newSmallJson = QFile{dir.path() + "/" + "app.json"};
newSmallJson.open(QIODevice::ReadWrite);
QTextStream stream(&newSmallJson);
stream << newJsonDocument.toJson() << Qt::endl;
newSmallJson.flush();
newSmallJson.close();
}
}
}
}
}
}
}
#endif // FUNCTIONS_H

View file

@ -190,7 +190,7 @@ generalDialog::generalDialog(QWidget *parent) :
QTimer::singleShot(50, this, SLOT(adjust_size()));
}
else if(global::userApps::appCompatibilityDialog == true) {
appCompabilityDialog = true;
appCompatibilityDialog = true;
global::userApps::appCompatibilityLastContinueStatus = true;
ui->okBtn->setText("Launch");
ui->cancelBtn->setText("Cancel");

View file

@ -32,7 +32,7 @@ public:
bool lowBatteryDialog = false;
bool usbmsDialog = false;
bool textBrowserDialog = false;
bool appCompabilityDialog = false;
bool appCompatibilityDialog = false;
bool appInfoDialog = false;
bool resetKoboxDialog = false;
bool keyboardDialog = false;

102
main.cpp
View file

@ -27,101 +27,6 @@
#include <QTextStream>
#include <QRect>
#include <QScreen>
#include <QDirIterator>
#include <QJsonDocument>
#include <QJsonParseError>
#include <QJsonObject>
#include <QJsonValue>
#include <QJsonArray>
void createMainJson()
{
QDirIterator appsDir("/mnt/onboard/onboard/.apps", QDirIterator::NoIteratorFlags);
QFile newJsonFile = QFile{"/mnt/onboard/onboard/.apps/apps.json"};
QJsonDocument newJsonDocument;
QJsonArray array;
while (appsDir.hasNext())
{
QDir dir(appsDir.next());
if(dir.exists() == true) {
if(dir.path().split("/").last().contains(".") == false) {
QFile jsonSmall = QFile{dir.path() + "/app.json"};
if(jsonSmall.exists() == true) {
jsonSmall.open(QIODevice::ReadOnly | QIODevice::Text);
QString jsonString = jsonSmall.readAll();
jsonSmall.close();
QJsonDocument jsonSmallDoc = QJsonDocument::fromJson(jsonString.toUtf8());
if(jsonSmallDoc["app"].isObject() == true) {
QJsonObject jsonSmallMainObj = jsonSmallDoc["app"].toObject();
array.append(jsonSmallMainObj);
}
else {
log("Small JSON user application file is missing main object 'app'", "main");
}
}
else {
QString message = "User applications folder does not contain any 'app.json' file: ";
message.append(jsonSmall.fileName());
log(message, "main");
}
}
}
}
// https://forum.qt.io/topic/104791/how-i-can-create-json-format-in-qt/5
QJsonObject root;
root["list"] = array;
newJsonDocument.setObject(root);
newJsonFile.open(QFile::WriteOnly | QFile::Text | QFile::Truncate);
newJsonFile.write(newJsonDocument.toJson());
newJsonFile.flush();
newJsonFile.close();
}
void createSmallJsonFiles()
{
QFile jsonFile = QFile{"/mnt/onboard/onboard/.apps/apps.json"};
jsonFile.open(QIODevice::ReadOnly | QIODevice::Text);
QString fileRead = jsonFile.readAll();
jsonFile.close();
QJsonDocument jsonDocument = QJsonDocument::fromJson(fileRead.toUtf8());
if(jsonDocument["list"].isArray() == true) {
QJsonArray jsonArray = jsonDocument["list"].toArray();
for(QJsonValueRef refJsonObject: jsonArray) {
QJsonObject jsonMainObject = refJsonObject.toObject();
QString appName = jsonMainObject["Name"].toString();
// This needs to be here and not at the beggining of this function because it is an iterator
QDirIterator appsDir("/mnt/onboard/onboard/.apps", QDirIterator::NoIteratorFlags);
while (appsDir.hasNext()) {
QDir dir(appsDir.next());
if(dir.exists() == true) {
if(dir.path().split("/").last().toLower().contains(appName.toLower()) == true) {
QJsonObject root;
root["app"] = refJsonObject.toObject();;
QJsonDocument newJsonDocument;
newJsonDocument.setObject(root);
QFile newSmallJson = QFile{dir.path() + "/" + "app.json"};
newSmallJson.open(QIODevice::ReadWrite);
QTextStream stream(&newSmallJson);
stream << newJsonDocument.toJson() << Qt::endl;
newSmallJson.flush();
newSmallJson.close();
}
}
}
}
}
}
int main(int argc, char *argv[])
{
@ -142,6 +47,13 @@ int main(int argc, char *argv[])
log("Device does not have Wi-Fi capabilities", "main");
global::device::isWifiAble = false;
}
if(QFile::exists("/tmp/rescan_userapps")) {
QFile::remove("/tmp/rescan_userapps");
log("Re-scanning user applications from explicit request", "main");
updateUserAppsMainJsonFile();
}
if(checkconfig(".config/18-encrypted_storage/status") == true and checkconfig("/external_root/run/encfs_mounted") == false) {
// Open Encryption Manager to unlock encrypted storage
QApplication a(argc, argv);

View file

@ -51,6 +51,9 @@ void quit::on_pushButton_clicked()
global::battery::showCriticalBatteryAlert = false;
global::battery::showLowBatteryDialog = false;
// GUI apps
updateUserAppsMainJsonFile();
poweroff(true);
qApp->quit();
}
@ -60,6 +63,9 @@ void quit::on_pushButton_2_clicked()
global::battery::showCriticalBatteryAlert = false;
global::battery::showLowBatteryDialog = false;
// GUI apps
updateUserAppsMainJsonFile();
reboot(true);
qApp->quit();
}

View file

@ -85,6 +85,9 @@ void usbms_splash::usbms_launch()
string_writeconfig("/opt/ibxd", "usbnet_stop\n");
QThread::msleep(1000);
string_writeconfig("/opt/ibxd", "gui_apps_stop\n");
QThread::msleep(1000);
if(global::deviceID == "n306\n" or global::deviceID == "n873\n") {
QProcess::execute("insmod", QStringList() << "/external_root/lib/modules/fs/configfs/configfs.ko");
QProcess::execute("insmod", QStringList() << "/external_root/lib/modules/drivers/usb/gadget/libcomposite.ko");
@ -197,6 +200,22 @@ void usbms_splash::restartServices() {
string_writeconfig("/opt/ibxd", "update_inkbox_restart\n");
QThread::msleep(2500);
string_writeconfig("/tmp/in_usbms", "false");
// GUI apps: update main JSON file
string_writeconfig("/opt/ibxd", "gui_apps_start\n");
while(true) {
if(QFile::exists("/tmp/gui_apps_started")) {
if(checkconfig("/tmp/gui_apps_started") == true) {
QFile::remove("/tmp/gui_apps_started");
updateUserAppsMainJsonFile();
break;
}
else {
log("GUI apps service failed to start", className);
QFile::remove("/tmp/gui_apps_started");
break;
}
}
}
quit_restart();
}

View file

@ -30,8 +30,7 @@ void userapps::provideInfo(QJsonObject jsonInfo)
appName = name; // It is for searching for json entry while disabling / enabling
jsonObject = jsonInfo;
// Limit name size to avoid breaking the GUI
if(name.size() > 20)
{
if(name.size() > 20) {
// If someone wants to break the GUI, they will do it ¯\^-^/¯
name.remove(16, 100);
}
@ -91,7 +90,7 @@ void userapps::on_statusBtn_clicked()
{
ui->statusBtn->setEnabled(false);
// Here the text on this button is used as a bool. No need to create a new one
// Here the text on this button is used as a boolean; no need to create a new one
// Disable and Enable
if(userAppEnabled == false) {
userAppEnabled = true;
@ -107,13 +106,11 @@ void userapps::on_statusBtn_clicked()
int arraySize = jsonArrayList.size();
for(int i = 0; i < arraySize; i++)
{
for(int i = 0; i < arraySize; i++) {
QJsonObject jsonObject = jsonArrayList.at(i).toObject();
QString entryName = jsonObject["Name"].toString();
if(entryName == appName)
{
if(entryName == appName) {
jsonObject.insert("Enabled", QJsonValue(userAppEnabled));
QJsonArray sonArrayListNew = jsonDocument.object()["list"].toArray();
@ -173,8 +170,7 @@ void userapps::on_launchBtn_clicked()
bool userapps::manageRequiredFeatures()
{
QJsonArray jsonArray = jsonObject["RequiredFeatures"].toArray();
for(QJsonValueRef refJsonObject: jsonArray)
{
for(QJsonValueRef refJsonObject: jsonArray) {
bool launchDialog = false;
int featureId = refJsonObject.toInt();
// Wi-Fi connection required
@ -188,16 +184,14 @@ bool userapps::manageRequiredFeatures()
launchDialog = true;
}
if(launchDialog == true)
{
if(launchDialog == true) {
global::userApps::appCompatibilityDialog = true;
generalDialogWindow = new generalDialog();
generalDialogWindow->setAttribute(Qt::WA_DeleteOnClose);
generalDialogWindow->exec();
}
if(global::userApps::appCompatibilityLastContinueStatus == false)
{
if(global::userApps::appCompatibilityLastContinueStatus == false) {
return false;
}
}
@ -226,11 +220,10 @@ QString userapps::parseJsonShow(QJsonObject json)
QJsonArray array = value.toArray();
for(QJsonValueRef ref: array) {
int id = ref.toInt();
if(id == 0)
{
if(id == 0) {
appendString.append("Wi-Fi connection");
} else if(id == 1)
{
}
else if(id == 1) {
appendString.append("Rooted kernel");
}
appendString.append(", ");